let { (<|) } = import! std.function let { Test, run, assert, assert_eq, test, group, ? } = import! std.test let { LazyT, force_t, ? } = import! std.lazyt let { Functor, map } = import! std.functor let { Applicative, wrap, (*>) } = import! std.applicative let { Monad, (>>=) } = import! std.monad let { Transformer, wrap_monad } = import! std.transformer let { Option, unwrap, ? } = import! std.option let { (++), ? } = import! std.string let list @ { List, ? } = import! std.list let left_identity x f : [Eq a] -> [Show a] -> a -> (a -> LazyT Option a) -> _ = \_ -> let mx : LazyT Option _ = wrap x assert_eq (force_t (mx >>= f)) (force_t (f x)) let right_identity x : [Eq a] -> [Show a] -> a -> _ = \_ -> let mx : LazyT Option _ = wrap x assert_eq (force_t (mx >>= wrap)) (force_t mx) let associativity mx f g : [Monad m] -> [Show (m a)] -> [Eq (m a)] -> m a -> _ -> _ -> _ = \_ -> let mx : LazyT m _ = wrap_monad mx assert_eq (force_t ((mx >>= f) >>= g)) (force_t (mx >>= (\x -> f x >>= g))) group "lazyt" [ group "LazyT m is monadic" [ test "left identity" <| left_identity 324 (\x -> wrap <| x + 89), test "right identity" <| right_identity "hello", test "associativity" <| associativity (Some 5) (\x -> wrap (x+5)) (\x -> wrap (x*2)), ], let x = list.of [8,6,7,5,3,0,9] let f = (*) 42 test "LazyT m is lazy" <| \_ -> assert_eq (map f x) (force_t <| map f <| wrap_monad x), ]