据我所知,如果你有很多类型的函数,如 f: a -> m[b]
而且只要它们都返回用 m
你应该可以通过 do/bind/flatMap
:
f: A -> M[B]
g: B -> M[C]
h: C -> M[D]
这是很直接的,可以通过 >>=
或 flatMap
(Scala)。
如何去组合那些在单体 "框 "中不同,但值 里面 是 "可连锁 "的?
f: A -> M[B]
g: B -> N[C]
h: C -> P[D]
我从来没有看到过这种情况,我知道我们可以。lift
单元,但这将失去目的IMO。这是单体构造的限制吗?我们甚至可以把它们连锁起来吗?解决这个问题的规范方法是什么?
正如 @Luis Miguel Mejía Suárez 所说的那样,单项式并不组成。如果你有 M[A]
, N[B]
和 O[C]
你不能只是把它们组合成... 具体是什么?
你可能想把它们组合成这样的东西 M[N[O[D]]]
. 但有 flatMap
只能在最外层的单体上运行。如果你的计算要通过所有的层,你必须为除了最外层以外的每一层都有一个单项式变换器。
这种组合类型能不能从盒子里生成?也不是因为 M[N[O[D]]]
不等于 O[N[M[D]]]
而应该有一些方法来决定顺序的确定性方式。
你可以将自然变换传递到 Target[_]
中的每一个类型,这将使您可以转换为 M[A]
, N[B]
和 O[C]
变成 Target[A]
, Target[B]
和 Target[C]
并将它们组合成单体,但这远不是简单的事情。
还有一些方法,不使用特定的 M[_]
, N[_]
, O[_]
你把它们作为参数,把Target作为参数,并以某种方式能够添加和影响类型并执行它 - 。Freer
,其优化形式为 Eff
和代数效果就是这样一种方式,它可以创建一个类型=级别的效果列表,并添加和删除它们(通过解释grunning一层)。据我所知,这些尝试是成功的,因为它们使得一般情况下可以做到它们所承诺的事情......但精神上的开销使得它们超级不实用,而且对大多数人来说很难理解。绝对的,不直接。有时也会误导人,因为他们有时会假装我们解释效果的顺序并不重要,而事实上它很重要。
目前,如果你需要堆叠效果,你更有可能使用无标签的final来使用一个,到处都是组成的效果,使用MTL类型的类来提供statereaderwriter等能力,旁边是monadic接口。而如果你要在效果之间进行转换,你就必须通过自然转换。
所以总结一下,总的来说这个问题还没有解决,甚至现在Haskell社区还在寻找一些新的解决方案。即使是现在,也有一个库的开发,比如 效益 和 多义词 据我所知,它们是免费的单片机,但有内置的编译器支持。目前你最多只能在前期决定你的聚合效果,或者通过TTFI和MTL推迟选择。只是把不同的单片机混在一起......不想想怎么写是不可能的。