sumtypes

Simple variant generator empowering easy heterogeneous type operations


Keywords
variant, sumtype, type
License
MIT
Install
nimble install sumtypes

Documentation

SumTypes - An easy to use Nim Sum Type library.

import sumtypes
type SumValues = string or int or float
sumType(SomeData, SumValues)
var a: SomeData = "hello world"
echo a
a = 100
echo a
a = 3.14
echo a

How to use

Sum Type

First define a typeclass of the types you want to store in the collection:

import sumtypes
type AcceptedTypes = int or float

Now you can use the sumType macro to emit a variant object based off the AcceptedTypes:

sumType(YourTyp, AcceptedTypes)

This emits a new type entitled YourTyp, which also comes with helper macro support which are as follows:

var a: YourTyp = 10 # Implicit converter

case a: # Custom case statement that works with types
of int:
  echo it # Unpacking of the type in a case statement
else: # Works for remaining types
  discard

a.unpack: # Unpacks it and runs the body on all kinds
  echo it 

a.unpack(someName): # Unpacks it as `someName`
  echo someName

a = 3.1415 # Implicit converter

SumTypeSeq

Now you can construct the SumTypeSeq objects and procedures by doing:

sumTypeSeq(IntFloat, AcceptedTypes)

This emits an enum, procedures, and types. Internally this library makes a object variant per each type. Now you can mostly treat this new collection like you would a seq:

var yourSeq: IntFloat
yourSeq.add 100
yourSeq.add 1.0

Along with those helpers there are also a variety of helper macros:

assert yourSeq.toSeq(float) == @[1.0] # `toSeq` will return a new seq of the type queried.
yourSeq.drop(float) # This will remove all instances of the `float` variant from the list.
yourSeq.filter(int) # This will remove all other types other than `int`
assert yourSeq.len == 1

yourSeq[0] = 100 # Assigns `0` to a new variant with value 100.

yourSeq[0] = initIntFloatEntry(100) # The above is the same as doing this, makes new variant and assigns it.

unpack(yourSeq.pop): # Removes the last element, passing `it` into the body.
  echo it
assert yourSeq.len == 0

Just like with sumType a case statement macro which allows using types to control flow. Internally it is emitted for the unpacked value.

type AcceptedTypes = float or int
sumTypeSeq(Numbers, AcceptedTypes)
var a: Numbers
a.add(100)
a.add(1.0)

for x in a:
  case x:
  of int: echo "Hey int: ", it
  of float: echo "Hey float: ", it

There is also a unpack macro which allows unpacking to the root value and running the code for all types. Internally it is emitted for the body.

for x in a:
  unpack(x):
    echo it
  x.unpack(someVal): # Also can control aliasing
    echo someVal