## Universal structure

The Universal structure provides a universal union type. It allows value of any type to be stored in a single table without knowing in advance the types to be stored. Note that this is not the same as a dynamic type. The values are discriminated by the tag, not by the type. There may be more than one tag that can be used with values of a particular type and these are treated as completely different. Universal is built in for efficiency reasons but it is perfectly feasible to implement it in Standard ML using exception bindings.

    structure Universal:
      sig
        type universal
        type 'a tag
        val tag: unit -> 'a tag
        val tagInject: 'a tag -> 'a -> universal
        val tagIs: 'a tag -> universal -> bool
        val tagProject: 'a tag -> universal -> 'a
      end

    type universal

The type of the universal union.

    type 'a tag

The type of a tag that can be used to mark a value of the argument type.

    val tag: unit -> 'a tag

Create a tag that can be used to identify a value of a particular type.

    val tagInject: 'a tag -> 'a -> universal

Inject a value into the union. This marks the value with the tag.

    val tagIs: 'a tag -> universal -> bool

Test whether the value was marked with the tag.

    val tagProject: 'a tag -> universal -> 'a

Project a value from the union. The tag must match the tag that was used to create union value otherwise a Match exception will be raised.