aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data/maybe.lux
blob: e2c0ce3fa05e4d339ef87d0fbd768e1e1ef30f78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(.module:
  [lux #*
   ["_" test (#+ Test)]
   [control
    pipe
    [monad (#+ do)]
    {[0 #test]
     [/
      [".T" functor (#+ Injection Comparison)]
      [".T" apply]
      [".T" monad]
      [".T" equivalence]]}]
   [data
    ["." text
     format]
    [number
     ["." nat]]]
   ["." io ("#@." monad)]
   [math
    ["r" random (#+ Random)]]]
  {1
   ["." / ("#@." monoid)]})

(def: injection
  (Injection Maybe)
  (|>> #.Some))

(def: comparison
  (Comparison Maybe)
  (function (_ ==)
    (:: (/.equivalence ==) =)))

(def: #export maybe
  (All [a] (-> (Random a) (Random (Maybe a))))
  (:: r.functor map (|>> #.Some)))

(def: #export test
  Test
  (<| (_.context (%name (name-of .Maybe)))
      ($_ _.and
          (equivalenceT.test (/.equivalence nat.equivalence) (..maybe r.nat))
          (functorT.laws ..injection ..comparison /.functor)
          (applyT.laws ..injection ..comparison /.apply)
          (monadT.laws ..injection ..comparison /.monad)
          (do r.monad
            [left r.nat
             right r.nat
             #let [expected (n/+ left right)]]
            (let [lift (/.lift io.monad)]
              (_.test "Can add maybe functionality to any monad."
                      (|> (io.run (do (/.with io.monad)
                                    [a (lift (io@wrap left))
                                     b (wrap right)]
                                    (wrap (n/+ a b))))
                          (case> (#.Some actual)
                                 (n/= expected actual)

                                 _
                                 false)))))
          (let [(^open "/@.") (/.equivalence text.equivalence)
                (^open "/@.") /.monoid]
            (_.test "Monoid respects Maybe."
                    (and (/@= #.None /@identity)
                         (/@= (#.Some "yolo") (/@compose (#.Some "yolo") (#.Some "lol")))
                         (/@= (#.Some "yolo") (/@compose (#.Some "yolo") #.None))
                         (/@= (#.Some "lol") (/@compose #.None (#.Some "lol")))
                         (/@= #.None (: (Maybe Text) (/@compose #.None #.None))))))
          (do r.monad
            [default r.nat
             value r.nat]
            (_.test "Can have defaults for Maybe values."
                    (and (is? default (/.default default
                                                 #.None))

                         (is? value (/.default default
                                               (#.Some value))))))
          )))