(.module: [lux #* ["_" test (#+ Test)] [abstract [monad (#+ do)] {[0 #test] [/ ["$." functor (#+ Injection Comparison)] ["$." apply] ["$." monad]]}] [data [text format]] [math ["r" random]]] {1 ["." / (#+ Reader) [// ["." io (#+ IO)]]]}) (def: (injection value) (Injection (All [a r] (Reader r a))) (function (_ env) value)) (def: comparison (Comparison (All [a r] (Reader r a))) (function (_ == left right) (== (/.run [] left) (/.run [] right)))) (def: #export test Test (<| (_.context (%name (name-of /._))) (do r.monad [sample r.nat factor r.nat] ($_ _.and ($functor.spec ..injection ..comparison /.functor) ($apply.spec ..injection ..comparison /.apply) ($monad.spec ..injection ..comparison /.monad) (_.test "Can query the environment." (n/= sample (/.run sample /.ask))) (_.test "Can modify an environment locally." (n/= (n/* factor sample) (/.run sample (/.local (n/* factor) /.ask)))) (let [(^open "io@.") io.monad] (_.test "Can add reader functionality to any monad." (|> (: (/.Reader Any (IO Nat)) (do (/.with io.monad) [a (/.lift (io@wrap sample)) b (wrap factor)] (wrap (n/* b a)))) (/.run []) io.run (n/= (n/* factor sample)))))))))