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