The OpenD Programming Language

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 No) $(TD )) $(TR $(TDNW $(LREF optionalVisit)) $(TD No) $(TD No) $(TD Yes) $(TD No) $(TD 1+) $(TD No) $(TD )) $(TR $(TDNW $(LREF autoVisit)) $(TD No) $(TD No) $(TD auto) $(TD No) $(TD 1+) $(TD No) $(TD )) $(TR $(TDNW $(LREF tryVisit)) $(TD No) $(TD Yes) $(TD No) $(TD No) $(TD 1+) $(TD No) $(TD ))

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

$(TR $(TDNW $(LREF suit)) $(TD N/A(Yes)) $(TD N/A) $(TD No) $(TD Yes) $(TD ?) $(TD Yes) $(TD )) $(TR $(TDNW $(LREF some)) $(TD N/A(Yes)) $(TD N/A) $(TD No) $(TD Yes) $(TD 0+) $(TD Yes) $(TD )) $(TR $(TDNW $(LREF none)) $(TD N/A(Yes)) $(TD N/A) $(TD No) $(TD Yes) $(TD 1+) $(TD Yes) $(TD )) $(TR $(TDNW $(LREF assumeOk)) $(TD Yes(No)) $(TD No(Yes)) $(TD No(Yes)) $(TD Yes(No)) $(TD 0+) $(TD Yes(No)) $(TD ))

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

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

Visitor Handlers

NameEnsures can matchThrows if no matchReturns NullableMultiple dispatchArgumments countFuses Algebraic types on return
Classic handlers
Multiple dispatch and algebraic fusion on return
Inner 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])
ErrWrapper to denote an error value type.
reflectErrAttribute that denotes that the type is an error value 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).
isTypeSetChecks if the types are the same as TypeSet of them.
ValueTypeOfNullableGets type of
  • .Algebraic.get.2
  • method.

    SomeVariantGets subtype of algebraic without types for which isErr is true.
    NoneVariantGets subtype of algebraic with types for which isErr is true.
    isErrChecks if T is a instance of Err or if it is annotated with reflectErr.
    isResultVariantChecks if T is a Variant with at least one allowed type that satisfy isErr traits.

    Members

    Aliases

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

    Nullable Variant Type (aka Algebraic Type).

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

    Variant Type (aka Algebraic Type).

    assumeOk
    alias assumeOk(alias visitor = naryFun!("", "a"), alias handler = .match) = handler!(some!visitor, none!throwMe)

    Validates that the result doesn't contain an error value.

    autoGetMember
    alias autoGetMember(string member, TArgs...) = visitImpl!(getMemberHandler!(member, TArgs), 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, TArgs...) = visitImpl!(getMemberHandler!(member, TArgs), 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, TArgs...) = visitImpl!(getMemberHandler!(member, TArgs), 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.

    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, TArgs...) = visitImpl!(getMemberHandler!(member, TArgs), 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.

    none
    alias none(visitors...) = suit!(anyArgumentIsInstanceOfErr, unwrapErr!(naryFun!visitors))

    some is a variant of suit that forces that type of any argument doesn't satisfy isErr template.

    optionalGetMember
    alias optionalGetMember(string member, TArgs...) = visitImpl!(getMemberHandler!(member, TArgs), 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, TArgs...) = visitImpl!(getMemberHandler!(member, TArgs), 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.

    some
    alias some(visitors...) = suit!(allArgumentsIsNotInstanceOfErr, naryFun!visitors)

    some is a variant of suit that forces that type of any argument doesn't satisfy isErr template.

    suit
    alias suit(alias filter, visitors...) = visitImpl!(naryFun!visitors, Exhaustive.compileTime, true, filter)
    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, TArgs...) = visitImpl!(getMemberHandler!(member, TArgs), 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

    algMeta
    enum algMeta

    The attribute is used to define a permanent member field in an anlgebraic type. Should applied to a field of the union passed to TaggedVariant.

    algTransp
    enum algTransp

    The attribute is used in pair with algMeta to exclude the field from compression in toHash, opEquals, and opCmp methods.

    algVerbose
    enum algVerbose

    The attribute is used in pair with algMeta to use the field as an error infomration. Usually it is a position marker in a file. The type should have scope const toString method.

    reflectErr
    enum reflectErr

    Attribute that denotes an error type. Can be used with some and none.

    Functions

    err
    auto err(T value)

    Wrapper to denote an error value type.

    nullable
    Nullable!T nullable(T t)

    Nullable Variant Type (aka Algebraic Type).

    Structs

    Algebraic
    struct Algebraic(T__...)

    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.

    This
    struct This

    Dummy type for Variant and Nullable self-referencing.

    Templates

    Err
    template Err(T)

    Wrapper to denote an error value type.

    NoneVariant
    template NoneVariant(T : Algebraic!Types, Types...)

    Gets subtype of algebraic with types for which isErr is true.

    SomeVariant
    template SomeVariant(T : Algebraic!Types, Types...)

    Gets subtype of algebraic without types for which isErr is true.

    TaggedVariant
    deprecated 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.

    isErr
    template isErr(T)

    Checks if T is a instance of Err or if it is annotated with reflectErr.

    isResultVariant
    template isResultVariant(T)

    Checks if T is a Variant with at least one allowed type that satisfy isErr traits.

    stripErr
    template stripErr(T)

    Strips out Err wrapper from the type.

    visitImpl
    template visitImpl(alias visitor, Exhaustive exhaustive, bool fused, alias Filter = _AcceptAll)
    Undocumented in source.

    Variables

    isLikeNullable
    enum bool isLikeNullable(T);

    Same as isNullable, but with support for custom alias this variants.

    isLikeTaggedVariant
    enum bool isLikeTaggedVariant(T);

    Same as isTaggedVariant, but with support for custom alias this variants.

    isLikeVariant
    enum bool isLikeVariant(T);

    Same as isVariant, but matches for alias this variant types (requires DMD FE 2.100.0 or later)

    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

    • 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.
    • some / none idiom.

    See Also

    Meta

    Authors

    Ilia Ki