Javascript 如何编写TaskT Monad Transformer以组合具有其他效果的异步计算?
我将monad transformers构造为的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的类型目录:
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来自解析和拒绝处理程序。因此,延续机制为我们处理它。毕竟,任务
只是一个额外的拒绝延续