The ContT
monad transformer has the same implementation like the Cont
monad, but I'm not able to apply it to all three Either
cases
Right
Left
from the current monadic actionLeft
from a previous monadic computation
The last one fails and all attempts to fix it failed as well:
const record = (type, o) => (
o[Symbol.toStringTag] = type.name || type,
o);
const union = type => (tag, o) => (
o[Symbol.toStringTag] = type,
o.tag = tag.name || tag,
o);
const match = (tx, o) => o[tx.tag] (tx);
const Either = union("Either");
const Left = left => Either(Left, {left});
const Right = right => Either(Right, {right});
const eithChain = mx => fm =>
match(mx, {
Left: _ => mx,
Right: ({right: x}) => fm(x)
});
const ContT = contt => record(ContT, {contt});
const contChainT = mmk => fmm =>
ContT(c => mmk.contt(x => fmm(x).contt(c)));
const main = foo =>
contChainT(ContT(k => k(foo))) (mx =>
eithChain(mx) (x =>
x === 0
? ContT(k => k(Left("ouch!")))
: ContT(k => k(Right(x * x)))));
main(Right(5)).contt(console.log); // Right(25)
main(Right(0)).contt(console.log); // Left("ouch!")
main(Left("yikes!")).contt(console.log); // Type Error
This is fruststrating. Any hints are much appreciated!