import union
type None = object
## A type for not having any data
proc search[T, U](x: T, needle: U): union(U | None) =
# Assignment can be done via explicit conversion
result = None() as union(U | None)
let idx = find(x, needle)
if idx >= 0:
# Or the `<-` operator which automatically converts the type
result <- x[idx]
assert [1, 2, 42, 20, 1000].search(10) of None
assert [1, 2, 42, 20, 1000].search(42) as int == 42
# For `==`, no explicit conversion is necessary
assert [1, 2, 42, 20, 1000].search(42) == 42
# Types that are not active at the moment will simply be treated as not equal
assert [1, 2, 42, 20, 1000].search(1) != None()
proc `{}`[T](x: seq[T], idx: Natural): union(T | None) =
## An array accessor for seq[T] but doesn't raise if the index is not there
# Using makeUnion, an expression may return more than one type
makeUnion:
if idx in 0 ..< x.len:
x[idx]
else:
None()
assert @[1]{2} of None
assert @[42]{0} == 42
import json
# With unpack(), dispatching based on the union type at runtime is possible!
var x = 42 as union(int | string)
block:
let j =
unpack(x):
# The unpacked variable name is `it` by default
%it
assert j.kind == JInt
x <- "string"
block:
let j =
# You can give the unpacked variable a different name via the second
# parameter, too.
unpack(x, upk):
%upk
assert j.kind == JString
See the documentation for more information on features and limitations of this module
This project is distributed under the terms of the MIT license.
See license.txt for more details.