Skip to content

Instantly share code, notes, and snippets.

@girvo
Created June 9, 2016 07:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save girvo/81f96c0fcddccb4541ae59287f999a0b to your computer and use it in GitHub Desktop.
Save girvo/81f96c0fcddccb4541ae59287f999a0b to your computer and use it in GitHub Desktop.
An Either monad(ish) implementation for Nim v0.14
## A right-biased Either[L, R] implementation in Nim
import optional_t
type
EitherType* {.pure.} = enum
Left, Right
Either*[L, R] = object
kind: EitherType
right: Option[R]
left: Option[L]
proc unsafeGetR*[R](self: Either[any, R]): R =
self.right.unsafeGet()
proc unsafeGetL*[L](self: Either[L, any]): L =
self.left.unsafeGet()
proc Right*[L, R](val: R): Either[L, R] =
result.right = Some[R](val)
result.left = None[L]()
result.kind = EitherType.Right
proc Left*[L, R](val: L): Either[L, R] =
result.left = Some[L](val)
result.right = None[R]()
result.kind = EitherType.Left
proc isLeft*[L, R](self: Either[L, R]): bool = ( self.kind == EitherType.Left )
proc isRight*[L, R](self: Either[L, R]): bool = ( self.kind == EitherType.Right )
proc map*[L, R, V](self: Either[L, R], oper: proc (input: R): V): Either[L, R] =
if self.isRight:
return Right[L, R](oper(self.unsafeGetR))
else:
return self
proc `$`*[L, R](self: Either[L, R]): string =
if self.isLeft:
result = "Left(" & $self.unsafeGetL & ")"
else:
result = "Right(" & $self.unsafeGetR & ")"
## Slightly dodgy usage examples...
proc aRight*() : Either[string, int] =
var test = Right[string, int](1234)
echo test.unsafeGetR
test = test.map do (val: int) -> int:
echo val
val + 1
test.map do (val: int) -> int:
echo val
val
proc aLeft*() : Either[string, int] =
result = Left[string, int]("This is an error!")
echo aRight()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment