Javascript 如何编写TaskT Monad Transformer以组合具有其他效果的异步计算?

Javascript 如何编写TaskT Monad Transformer以组合具有其他效果的异步计算?,javascript,functional-programming,monads,monad-transformers,Javascript,Functional Programming,Monads,Monad Transformers,我将monad transformers构造为的链/的变体,该变体带有一个附加参数-外部monad的类型目录: const无= ({runOption:null,标记:“None”,[Symbol.toStringTag]:“Option”}); const Some=x=> ({runOption:x,tag:“Some”,[Symbol.toStringTag]:“Option”}); 常数optOfT=of=>x=>of(某些(x)); 常量optChainT=({chain,of})=

我将monad transformers构造为的
/
的变体,该变体带有一个附加参数-外部monad的类型目录:

const无=
({runOption:null,标记:“None”,[Symbol.toStringTag]:“Option”});
const Some=x=>
({runOption:x,tag:“Some”,[Symbol.toStringTag]:“Option”});
常数optOfT=of=>x=>of(某些(x));
常量optChainT=({chain,of})=>fmm=>mmx=>
链(mx=>{
开关(mx.tag){
案例“无”:返回(无);
案例“部分”:返回fmm(mx.runOption);
}
})(mmx);
常数arrOf=x=>[x];
常量arrChain=fm=>xs=>
x.reduce((acc,x)=>arrPushFlat(acc)(fm(x)),[]);
常数=xs=>ys=>{
ys.forEach(x=>
推挤(x));
返回xs;
};
常量xs=[Some(“foo”)、None、Some(“bar”)];
console.log(
optChainT({chain:arrChain,of:arrOf})

(s=>[Some(s.toUpperCase())](xs));//[Some(“FOO”)、None、Some(“BAR”)]
问题中的
tChainT
函数由于类型错误而无法正常工作

constchaint=({chain,of})=>fmm=>mmx=>
链(mx=>
tChain(fmm)(mx)//A
)(mmx);
//可以简化为
常量tChainT=({chain})=>fmm=>chain(tChain(fmm));
//tChain::(a->任务e b)->任务e a->任务e b
//                                                 |______|    |____|
//                                                    |          |
//链::单子m=>(a->MB)->MA->MB
//                    _|__                                                 _|__    __|___       _|__
//                   |    |                                               |    |  |      |     |    |
//tChainT::Monad(任务e)=>(a->任务e b)->任务e(任务e a)->任务e b

来自的
tChainT
函数的类型也不正确

//tChainT::Monad m=>(a->Task e b)->m(Task e a)->m(Task e b)
常量tChainT=({chain,of})=>fm=>mmx=>
链(mx=>
of(tChain(fm)(mx))(mmx);//***A***
请注意,
fm
的返回类型是
Task eb
,而不是
m(Task eb)
。因此,
tChainT
不会返回有效的一元绑定函数。实际上,不可能创建一个类型为
Monad m=>(a->m(Task eb))->m(Task ea)->m(Task eb)
的函数,因为
m(Task ea)
taskte
Monad转换器的错误结构。正确的结构如下

//newtype TaskT e m a=TaskT{runTaskT::(a->m(),b->m())->m()}
const TaskT=runTaskT=>({[Symbol.toStringTag]:“TaskT”,runTaskT});
//tChainT::(a->TaskT e m b)->TaskT e m a->TaskT e m b
常量tChainT=f=>m=>TaskT((res,rej)=>
m、 runTaskT(x=>f(x).runTaskT(res,rej,rej));
//tOfT::a->TaskT e m a
常数tOfT=x=>TaskT((res,rej)=>res(x));
请注意,
tChainT
tOfT
分别与
tChain
tOf
具有相同的实现。这是因为
TaskT
的底层monad来自解析和拒绝处理程序。因此,延续机制为我们处理它。毕竟,
任务
只是一个额外的拒绝延续