gluon 0.13.1

A static, type inferred programming language for application embedding
Documentation
//@NO-IMPLICIT-PRELUDE
//! Monad transformer version of `Lazy`

let { Applicative, apply, wrap } = import! std.applicative
let { (<<) } = import! std.function
let { Functor, map } = import! std.functor
let { Lazy, lazy, force } = import! std.lazy
let { Monad, flat_map } = import! std.monad
let { Transformer } = import! std.transformer

type LazyT m a = Lazy (m a)

let functor : [Functor m] -> Functor (LazyT m) =
    let ltmap f ma = lazy (\_ -> map f (force ma))

    { map = ltmap }

let applicative : [Applicative m] -> Applicative (LazyT m) =
    let ltwrap a = lazy (\_ -> wrap a)
    let ltapply mf ma = lazy (\_ -> apply (force mf) (force ma))

    { functor, apply = ltapply, wrap = ltwrap }

let monad : [Monad m] -> Monad (LazyT m) =
    let ltflat_map f ma = lazy (\_ -> flat_map (force << f) (force ma))

    { applicative, flat_map = ltflat_map }

let transformer : Transformer LazyT =
    let wrap_monad ma : [Monad m] -> m a -> LazyT m a = lazy (\_ -> ma)

    { /* monad, */ wrap_monad }

let force_t : LazyT m a -> m a = force

{
    LazyT,

    force_t,

    functor,
    applicative,
    monad,
    transformer
}