查查Kleisli的定义,
猫中的
及其功能域和反应域建模
然而,我还不能理解它的用处。如果我们讨论组合一元函数的情况,比如返回单元的函数,即A => FB,我看不出它实际上增加了什么来简单地排列一个链
flatMapA, B(f: a => FB):FB
事实上,能够将上面的内容链接起来类似于
如果您有一个函数f: a => FB和另一个函数g: b => FC,其中F是一个单子函数,那么您可以组合它们以得到A => FC。
我没有看到什么是"Kleisli"的真正附加值?
发布于 2020-09-21 11:29:37
Kleisli只是形状A => F[B]函数的名称。
我们可以说,flatMap和Kleisli围绕着一个相似的想法,并与相似的概念联系在一起,但它们并不是一回事。两个人都没有“给另一个增加价值”。下面是他们之间的联系的一个例子:
Monad可以用几种不同但同样强大的方式来定义。一种是使用unit + flatMap,其法律定义为:
单位(X).flatMap(F) == f(x)
M.flatMap(单位) == m
f(x).flatMap(g)) m.flatMap(f).flatMap(g) == m.flatMap(x⇒m.flatMap)
另一种方法是使用unit + compose,其法律定义为:
unit.compose(f) == f
F.compose(单位) == f
(f.compose(g)).compose(h) f.compose(g.compose(h)) ==
在上述定义中,flatMap是您所知道的好的旧flatMap:
def flatMap: F[A] => (A => F[B]) => F[B]compose是Kleisli箭头的组成:
def compose: (A => F[B]) => (B => F[C]) => A => F[C]所以基本上都是关于术语的。它们经常在类似的背景下出现,但它们并不相同。它们只是两个相关但不同事物的名字。
发布于 2020-09-22 15:01:19
除了slouc给出的答案之外,我还想补充一句,我从未见过没有附加术语Kleisli而使用的术语composition。所以,你可能会说,分离出Kleisli函数的真正好处在于它们是如何组合的。
flatMap不是函数的组合。相反,它是对数据操作的排序。但是Kleisli组合(就像其他函数的组合一样)允许按照一定的规则从其他函数中创建新的函数--正如slouc所指出的。
在Haskell中,合成是用点运算符完成的。因此,如果f: A => B和g: B => C,您可以拥有:
h = g . f // h: A => C但是如果f和g是Kleisli函数(f: A => M[B]和g: B => M[C]),这是行不通的。这就是克莱斯里作曲发挥作用的地方。您经常会看到它被定义为“fish”操作符、>=>或类似的东西。使用Kleisli组合,您可以拥有:
h = g >=> f // h: A => M[C]顺便说一句,根据语言或库的不同,g和f在fish操作符中的顺序可能会颠倒。但这一概念仍然适用。您正在通过组合从两个现有函数构建一个新函数。稍后,您可以将此函数应用于数据,并得到与顺序应用程序flatMap相同的结果。
另一件我可能应该提到的事情是,由于Kleisli函数组成了一个适当的类别,所以您也会看到术语Kleisli Category。对于SW开发人员来说,它并不那么重要,但是我不得不处理它,因为我经常在文档和博客中看到它,所以我想我会把它传下去。
https://stackoverflow.com/questions/63990876
复制相似问题