mir.algebraic

Variant and Nullable types

This module implements a discriminated union type (a.k.a. tagged union, algebraic type). Such types are useful for type-uniform binary interfaces, interfacing with scripting languages, and comfortable exploratory programming.

The module defines generic Algebraic type that contains a payload. The allowed types of the paylad are defined by the unordered TypeSet.

Algebraic template accepts two arguments: self type set id and a list of type sets.

Algebraic Aliases

NameDescription
Variantan algebraic type
TaggedVarianta tagged algebraic type
Nullablean algebraic type with at least typeof(null)

$(TR $(TDNW $(LREF visit)) $(TD Yes) $(TD N/A) $(TD No) $(TD No) $(TD 1+) $(TD Yes) $(TD No)) $(TR $(TDNW $(LREF optionalVisit)) $(TD No) $(TD No) $(TD Yes) $(TD No) $(TD 1+) $(TD Yes) $(TD No)) $(TR $(TDNW $(LREF autoVisit)) $(TD No) $(TD No) $(TD auto) $(TD No) $(TD 1+) $(TD Yes) $(TD No)) $(TR $(TDNW $(LREF tryVisit)) $(TD No) $(TD Yes) $(TD No) $(TD No) $(TD 1+) $(TD Yes) $(TD No))

$(TR $(TDNW $(LREF match)) $(TD Yes) $(TD N/A) $(TD No) $(TD Yes) $(TD 0+) $(TD auto) $(TD Yes)) $(TR $(TDNW $(LREF optionalMatch)) $(TD No) $(TD No) $(TD Yes) $(TD Yes) $(TD 0+) $(TD auto) $(TD Yes)) $(TR $(TDNW $(LREF autoMatch)) $(TD No) $(TD No) $(TD auto) $(TD Yes) $(TD 0+) $(TD auto) $(TD Yes)) $(TR $(TDNW $(LREF tryMatch)) $(TD No) $(TD Yes) $(TD No) $(TD Yes) $(TD 0+) $(TD auto) $(TD Yes))

$(TR $(TDNW $(LREF getMember)) $(TD Yes) $(TD N/A) $(TD No) $(TD No) $(TD 1+) $(TD Yes) $(TD No)) $(TR $(TDNW $(LREF optionalGetMember)) $(TD No) $(TD No) $(TD Yes) $(TD No) $(TD 1+) $(TD Yes) $(TD No)) $(TR $(TDNW $(LREF autoGetMember)) $(TD No) $(TD No) $(TD auto) $(TD No) $(TD 1+) $(TD Yes) $(TD No)) $(TR $(TDNW $(LREF tryGetMember)) $(TD No) $(TD Yes) $(TD No) $(TD No) $(TD 1+) $(TD Yes) $(TD No))

$(TR $(TDNW $(LREF matchMember)) $(TD Yes) $(TD N/A) $(TD No) $(TD No) $(TD 1+) $(TD Yes) $(TD Yes)) $(TR $(TDNW $(LREF optionalMatchMember)) $(TD No) $(TD No) $(TD Yes) $(TD No) $(TD 1+) $(TD Yes) $(TD Yes)) $(TR $(TDNW $(LREF autoMatchMember)) $(TD No) $(TD No) $(TD auto) $(TD No) $(TD 1+) $(TD Yes) $(TD Yes)) $(TR $(TDNW $(LREF tryMatchMember)) $(TD No) $(TD Yes) $(TD No) $(TD No) $(TD 1+) $(TD Yes) $(TD Yes))

Visitor Handlers

NameEnsures can matchThrows if no matchReturns NullableMultiple dispatchArgumments countAlgebraic first argumentFuses Algebraic types on return
Classic handlers
Multiple dispatch and algebraic fusion on return
Member access
Member access with algebraic fusion on return

$(TR $(TDNW <tt class="inline-code">void</tt>) $(TD It is usefull to indicate a possible return type of the visitor. Can't be accesed by reference.)) $(TR $(TDNW <tt class="inline-code">typeof(null)</tt>) $(TD It is usefull for nullable types. Also, it is used to indicate that a visitor can't match the current value of the algebraic. Can't be accesed by reference.))

$(TR $(TDNW <a class="xref" href="SetAlias.html">SetAlias</a><tt class="inline-code">!setId</tt>) $(TD Dummy structure that is used to construct cyclic-referencing lists of algebraic types.))

Special Types

NameDescription
ThisDummy structure that is used to construct self-referencing algebraic types. Example: Variant!(int, double, string, This*[2])
TaggedTypeDummy type used to associate tags with type.

Algebraic Traits

NameDescription
isVariantChecks if the type is instance of Algebraic.
isNullableChecks if the type is instance of Algebraic with a self TypeSet that contains typeof(null).
isTaggedVariantChecks if the type is instance of tagged Algebraic.
isTypeSetChecks if the types are the same as TypeSet of them.
ValueTypeOfNullableGets type of
  • .Algebraic.get.2
  • method.

    Members

    Aliases

    Nullable
    alias Nullable(T...) = Variant!(typeof(null), T)

    Nullable Variant Type (aka Algebraic Type).

    TaggedTypeSet
    alias TaggedTypeSet(string[] tagNames, T...) = TypeSet!(applyTags!(tagNames, T))

    Type set for tagged Variants self-referencing.

    TaggedVariant
    alias TaggedVariant(string[] tags, T...) = Variant!(applyTags!(tags, T))

    Tagged Variant Type (aka Tagged Algebraic Type).

    Variant
    alias Variant(T...) = Algebraic!(TypeSet!T)

    Variant Type (aka Algebraic Type).

    autoGetMember
    alias autoGetMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.auto_, false)

    Behaves as getMember but doesn't enforce at compile time that all types can be handled by the member visitor.

    autoMatch
    alias autoMatch(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.auto_, true)

    Behaves as match but doesn't enforce at compile time that all types can be handled by the visiting functions.

    autoMatchMember
    alias autoMatchMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.auto_, true)

    Behaves as matchMember but doesn't enforce at compile time that all types can be handled by the member visitor.

    autoVisit
    alias autoVisit(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.auto_, false)

    Behaves as visit but doesn't enforce at compile time that all types can be handled by the visiting functions.

    getMember
    alias getMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.compileTime, false)

    Applies a member handler to the given Variant depending on the held type, ensuring that all types are handled by the visiting handler.

    getTaggedTypeUnderlying
    alias getTaggedTypeUnderlying(T : TaggedType!(I, name), I, string name) = I

    Gets TaggedType underlying type.

    match
    alias match(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.compileTime, true)

    Applies a delegate or function to the given arguments depending on the held type, ensuring that all types are handled by the visiting functions.

    matchMember
    alias matchMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.compileTime, true)

    Applies a member handler to the given Variant depending on the held type, ensuring that all types are handled by the visiting handler.

    optionalGetMember
    alias optionalGetMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.nullable, false)

    Behaves as getMember but doesn't enforce at compile time that all types can be handled by the member visitor.

    optionalMatch
    alias optionalMatch(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.nullable, true)

    Behaves as match but doesn't enforce at compile time that all types can be handled by the visiting functions.

    optionalMatchMember
    alias optionalMatchMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.nullable, true)

    Behaves as matchMember but doesn't enforce at compile time that all types can be handled by the member visitor.

    optionalVisit
    alias optionalVisit(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.nullable, false)

    Behaves as visit but doesn't enforce at compile time that all types can be handled by the visiting functions.

    tryGetMember
    alias tryGetMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.exception, false)

    Behaves as getMember but doesn't enforce at compile time that all types can be handled by the member visitor.

    tryMatch
    alias tryMatch(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.exception, true)

    Behaves as match but doesn't enforce at compile time that all types can be handled by the visiting functions.

    tryMatchMember
    alias tryMatchMember(string member) = visitImpl!(getMemberHandler!member, Exhaustive.exception, true)

    Behaves as matchMember but doesn't enforce at compile time that all types can be handled by the member visitor.

    tryVisit
    alias tryVisit(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.exception, false)

    Behaves as visit but doesn't enforce at compile time that all types can be handled by the visiting functions.

    visit
    alias visit(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.compileTime, false)

    Applies a delegate or function to the given Variant depending on the held type, ensuring that all types are handled by the visiting functions.

    Enums

    getTaggedTypeName
    eponymoustemplate getTaggedTypeName(T : TaggedType!(I, name), I, string name)

    Gets TaggedType tag name.

    isTaggedType
    eponymoustemplate isTaggedType(T)

    Checks if T is TaggedType instance.

    Functions

    nullable
    Nullable!T nullable(T t)

    Nullable Variant Type (aka Algebraic Type).

    Structs

    Algebraic
    struct Algebraic(_Types...)

    Algebraic implementation. For more portable code, it is higly recommeded to don't use this template directly. Instead, please use of Variant and Nullable, which sort types.

    TaggedType
    struct TaggedType(T, string name)

    Dummy type used to associate tags with a type.

    This
    struct This

    Dummy type for Variant and Nullable self-referencing.

    Templates

    TaggedVariant
    template TaggedVariant(T)

    Tagged Variant Type (aka Tagged Algebraic Type).

    TypeSet
    template TypeSet(T...)

    Type set resolution template used to construct Algebraic .

    ValueTypeOfNullable
    template ValueTypeOfNullable(T : Algebraic!(typeof(null), Types), Types...)

    Gets type of

  • .Algebraic.get.2
  • method.

    Variables

    isNullable
    enum bool isNullable(T);

    Checks if the type is instance of Algebraic with a self TypeSet that contains typeof(null).

    isTaggedVariant
    enum bool isTaggedVariant(T);

    Checks if the type is instance of tagged Algebraic.

    isTypeSet
    enum bool isTypeSet(T...);

    Checks if the type list is TypeSet.

    isVariant
    enum bool isVariant(T);

    Checks if the type is instance of Algebraic.

    Detailed Description

    Type Set

    • TaggedTypeSet is supported. Example:TargetTypeSet!(["integer", "floating"], int, double)
    • .

    • Type set is unordered. Example:TypeSet!(int, double) and TypeSet!(double, int) are the same.
    • Duplicats are ignored. Example: TypeSet!(float, int, float) and TypeSet!(int, float) are the same.
    • Types are automatically unqualified if this operation can be performed implicitly. Example: TypeSet!(const int) and TypeSet!int` are the same.
    • Non trivial TypeSet!(A, B, ..., etc) is allowed.
    • Trivial TypeSet!T is allowed.
    • Empty TypeSet!() is allowed.

    Visitors

    • Visitors are allowed to return values of different types If there are more then one return type then the an Algebraic type is returned.
    • Visitors are allowed to accept additional arguments. The arguments can be passed to the visitor handler.
    • Multiple visitors can be passes to the visitor handler.
    • Visitors are matched according to the common Dlang Function Overloading rules.
    • Visitors are allowed accept algebraic value by reference except the value of typeof(null).
    • Visitors are called without algebraic value if its algebraic type is void.
    • If the visitors arguments has known types, then such visitors should be passed to a visitor handler before others to make the compiler happy. This includes visitors with no arguments, which is used to match void type.

    Implementation Features

    • BetterC support. Runtime TypeInfo is not used.
    • Copy-constructors and postblit constructors are supported.
    • toHash, opCmp. opEquals, and toString support.
    • No string or template mixins are used.
    • Optimised for fast execution.

    See Also

    Meta

    License

    Apache-2.0

    Authors

    Ilya Yaroshenko