Advertisement
Guest User

Nim: algebraic-data-types, fmap, functor, Maybe, Either

a guest
Oct 8th, 2017
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 2.68 KB | None | 0 0
  1. type
  2.   MaybeKind = enum Just, Nothing
  3.   Maybe[T]  = object
  4.     case kind: MaybeKind
  5.       of Just: value: T
  6.       of Nothing: discard
  7.  
  8.   EitherKind   = enum Left, Right
  9.   Either[L, R] = object
  10.     case kind: EitherKind
  11.       of Left:  left:  L
  12.       of Right: right: R
  13.  
  14. let
  15.   a = Maybe[int32](kind: Nothing)
  16.   b = Maybe[int32](kind: Just, value: 9000)
  17.   c = Maybe[int32](kind: Just, value: 9000)
  18.   d = Maybe[int32](kind: Just, value: 100)
  19.   e = Maybe[int32](kind: Nothing)
  20.  
  21.   aa = Maybe[uint16](kind: Nothing)
  22.   ab = Maybe[uint16](kind: Nothing)
  23.   ac = Maybe[uint16](kind: Just, value: 10)
  24.   ad = Maybe[uint16](kind: Just, value: 10)
  25.   ae = Maybe[uint16](kind: Just, value: 20)
  26.  
  27.   ba = Either[uint, bool](kind: Left,  left: 5)
  28.   bb = Either[uint, bool](kind: Left,  left: 5)
  29.   bc = Either[uint, bool](kind: Right, right: true)
  30.   bd = Either[uint, bool](kind: Right, right: true)
  31.   be = Either[uint, bool](kind: Right, right: false)
  32.   bf = Either[uint, bool](kind: Left,  left: 6)
  33.  
  34. proc `==`[T](a: Maybe[T], b: Maybe[T]): bool =
  35.   case a.kind
  36.     of Nothing: b.kind == Nothing
  37.     of Just:    b.kind == Just and a.value == b.value
  38.  
  39. proc `==`[L, R](a: Either[L, R], b: Either[L, R]): bool =
  40.   case a.kind
  41.     of Left:  b.kind == Left  and a.left  == b.left
  42.     of Right: b.kind == Right and a.right == b.right
  43.  
  44. proc `<$>`[A, B](f: (proc (x: A): B); a: Maybe[A]): Maybe[B] =
  45.   case a.kind
  46.     of Just: Maybe[B](kind: Just, value: a.value.f)
  47.     of Nothing: Maybe[B](kind: Nothing)
  48.  
  49. proc `<$>`[L, R, N](f: (proc (x: R): N); a: Either[L, R]): Either[L, N] =
  50.   case a.kind
  51.     of Right: Either[L, N](kind: Right, right: a.right.f)
  52.     of Left:  Either[L, N](kind: Left, left: a.left)
  53.  
  54. assert(a == e)
  55. assert(b == c)
  56. assert(b != d)
  57. assert(c != d)
  58. assert(a != b)
  59. assert(b != e)
  60.  
  61. assert(aa == ab)
  62. assert(ab != ac)
  63. assert(ac == ad)
  64. assert(ad != ae)
  65. assert(ac != ae)
  66.  
  67. assert(ba == bb)
  68. assert(bb != bc)
  69. assert(bc == bd)
  70. assert(bd != be)
  71. assert(be != bf)
  72. assert(ba != bf)
  73.  
  74. proc divBy2(x: int32): int32 = x div 2
  75. proc divBy2x(x: int32): int16 = int16 x div 2
  76. let b2: Maybe[int32] = divBy2 <$> b
  77. let b3: Maybe[int16] = divBy2x <$> b
  78. assert(b.kind == Just and b.value == 9000)
  79. assert(b2.kind == Just and b2.value == 4500)
  80. assert(b3.kind == Just and b3.value == 4500)
  81.  
  82. proc mult(x: int16): int32 = x * 2
  83.  
  84. let
  85.   ca = Either[bool, int16](kind: Left,  left: true)
  86.   cb = Either[bool, int16](kind: Right, right: 5)
  87.   cc: Either[bool, int32] = mult <$> ca
  88.   cd: Either[bool, int32] = mult <$> cb
  89.  
  90. assert(ca.kind == Left  and ca.left == true)
  91. assert(cb.kind == Right and cb.right == 5)
  92. assert(cc.kind == Left  and cc.left == true)
  93. assert(cd.kind == Right and cd.right == 10)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement