I am implementing the monad transformer of the Maybe
(aka Option
) type in Javascript (please note that I use type-dictionary passing):
const optOfT = of => x =>
of(optOf(x));
const optMapT = map => f => ttx =>
map(optMap(f)) (ttx);
const optApT = chain => ttf => ttx =>
chain(tf =>
chain(tx =>
optAp(tf) (tx)) (ttx)) (ttf);
const optChainT = chain => fm => mmx =>
chain(mx =>
optChain(fm) (mx)) (mmx);
(map ~ <$>
, ap ~ <*>
, chain ~ =<<
, of = pure/return)
While this code works I wonder if I can implement optApT
without the monad constraint for the outer monad. I stumbled upon this Haskell example:
(<<**>>) :: (Applicative a, Applicative b) => a (b (s -> t)) -> a (b s) -> a (b t)
abf <<**>> abs = pure (<*>) <*> abf <*> abs
This seems exactly what I want, but I can't recognize the evaluation order of pure (<*>) <*> abf <*> abs
and which <*>
operator belongs to which applicative layer:
const optApT = (ap, of) => ttf => ttx =>
...?
Any hint is appreciated.