Skip to content

Instantly share code, notes, and snippets.

@z-------------
Last active January 13, 2023 13:19
Show Gist options
  • Save z-------------/ef52236ecb2f6b6ba7168ba4da26c719 to your computer and use it in GitHub Desktop.
Save z-------------/ef52236ecb2f6b6ba7168ba4da26c719 to your computer and use it in GitHub Desktop.
type
Either*[A, B] = object
case isA: bool
of true:
a: A
of false:
b: B
template isB(e: Either): bool =
not e.isA
func `$`*(e: Either): string =
if e.isA:
$e.a
else:
$e.b
func init*[A, B](_: typedesc[Either[A, B]]; a: sink A): Either[A, B] =
Either[A, B](isA: true, a: a)
func init*[A, B](_: typedesc[Either[A, B]]; b: sink B): Either[A, B] =
Either[A, B](isA: false, b: b)
func init*[A, B](_: typedesc[Either]; a: sink A; bType: typedesc[B]): Either[A, B] =
Either[A, B](isA: true, a: a)
func init*[A, B](_: typedesc[Either]; aType: typedesc[A]; b: sink B): Either[A, B] =
Either[A, B](isA: false, b: b)
func isOf*[A, B](e: Either[A, B]; _: typedesc[A]): bool =
e.isA
func isOf*[A, B](e: Either[A, B]; _: typedesc[B]): bool =
e.isB
func get*[A, B](e: Either[A, B]; _: typedesc[A]): lent A =
assert e.isA
e.a
func get*[A, B](e: Either[A, B]; _: typedesc[B]): lent B =
assert e.isB
e.b
func isLeft*[A, B](e: Either[A, B]): bool =
e.isA
func isRight*[A, B](e: Either[A, B]): bool =
e.isB
func left*[A, B](e: Either[A, B]): lent A =
assert e.isA
e.a
func right*[A, B](e: Either[A, B]): lent B =
assert e.isB
e.b
when isMainModule:
import std/sugar
block:
let e = Either.init(int, "hello")
dump typeof e
dump e
dump e.isOf(string)
dump e.isOf(int)
dump e.get(string)
dump e.isLeft
dump e.isRight
dump e.right
block:
let e = Either.init(42, int)
dump typeof e
dump e
dump compiles(e.isOf(int))
dump compiles(e.get(int))
dump e.isLeft
dump e.isRight
dump e.left
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment