【问题标题】:Kleisli vs flapMap SequencingKleisli 与 FlapMap 测序
【发布时间】:2020-09-21 10:56:02
【问题描述】:

检查 Kleisli 定义,

在 Cats 以及函数式和反应式领域建模中

但是我还不能掌握它的用处。如果我们谈论组合 Monadic 函数的情况,例如在返回 monad 的函数中,即 A => F[B],我看不出它实际上添加了什么来简单地对链进行排序

flatMap[A, B](ma: F[A])(f: A => F[B]): F[B]

确实,能够链接上述内容类似于

如果你有一个函数 f: A => F[B] 和另一个函数 g: B => F[C],其中 F 是一个单子,那么你可以组合它们得到 A => F[C]

"Kleisli" 的真正附加价值是什么?

【问题讨论】:

  • Kleisli 箭头是在上下文中返回值的函数,它们由 Kleisli 组合组成。 flatmap 是上下文中的应用程序,而 Kleisli 组合是上下文中的组合,并导致无点样式代码。
  • 无点样式代码????
  • flatMap 用于组成 Monads效果值Kleisli arrow 被使用组合产生效果值(即Monads)的函数。因此,这只是您是否要组合值或函数;即与y = g(f(x)) VS h = f andThen g - y = h(x) 的区别相同。

标签: scala functional-programming purely-functional


【解决方案1】:

Kleisli 只是形状函数A => F[B] 的名称。

我们可以说 flatMap 和 Kleisli 围绕着一个相似的想法,并且与相似的概念相关联,但它们并不是一回事。两者都没有“为另一个增加价值”。以下是他们的联系示例:

Monad 可以用几种不同但同样强大的方式定义。一种是使用unit + flatMap,其规律定义为:

  • 左恒等式:

         unit(x).flatMap(f) == f(x)
    
  • 权利身份法:

         m.flatMap(unit) == m
    
  • 结合律:

         m.flatMap(f).flatMap(g) == m.flatMap(x ⇒ f(x).flatMap(g))
    

另一种方法是使用unit + compose,其规律定义为:

  • 左恒等式:

        unit.compose(f) == f
    
  • 权利身份法:

         f.compose(unit) == f
    
  • 结合律:

         f.compose(g.compose(h)) == (f.compose(g)).compose(h)
    

在上述定义中,flatMap 是您所知道的旧式平面地图:

def flatMap: F[A] => (A => F[B]) => F[B]

compose是Kleisli箭头的组成:

def compose: (A => F[B]) => (B => F[C]) => A => F[C]

所以基本上都是关于术语的。它们经常出现在相似的上下文中,但它们并不相同。它们只是两个相关但不同事物的名称。

【讨论】:

  • 啊,按照你的说法,Kleisi with Unit 是构成单子的充分法则之一。就像襟翼地图和单位一样。
  • 差不多。不是 Kleisli,而是 Kleisli 的组合。因此,在这两种情况下,您都使用 Kleisli ( A => F[B] ),但在一种情况下,您还拥有 F[A] 并对其进行 flatMap,而在另一种情况下,您拥有另一个 Kleisli 并使用它进行创作。跨度>
  • @MaatDeamon 顺便说一句,您可能想要编辑您的问题,因为您从未真正引用过 Kleisli 定义;您刚刚说“在 Cats 以及功能和反应式领域建模中”
【解决方案2】:

除了 slouc 给出的答案之外,我认为补充一点很有用,我从来没有真正看到在没有附加术语 composition 的情况下使用术语 Kleisli。因此,您可能会说,分离出 Kleisli 函数的真正好处在于如何组合它们。

flatMap 不是函数的组合。相反,它是对数据的一系列操作。但是 Kleisli 组合(就像其他函数的组合一样)允许按照某些规则从其他函数创建新函数 - 正如 slouc 所指出的那样。

在 Haskell 中,组合是使用点运算符完成的。所以,如果f: A => Bg: B => C,你可以有:

h = g . f       // h: A => C

但如果 fg 是 Kleisli 函数(f: A => M[B]g: B => M[C]),这将不起作用。这就是 Kleisli 组合发挥作用的地方。您经常看到它被定义为“鱼”运算符>=> 或类似的东西。使用 Kleisli 组合,您可以:

h = g >=> f      // h: A => M[C]

顺便说一句,根据语言或库的不同,fish 运算符中gf 的顺序可能会颠倒。但这个概念仍然适用。您正在通过组合从两个现有函数构建一个新函数。稍后,您可以将此函数应用于数据,并获得与连续应用flatMap 相同的结果。

我可能应该提到的另一件事是,由于 Kleisli 函数组成了一个适当的类别,因此您还会看到术语 Kleisli Category。这对 SW 开发人员来说并不是那么重要,但我必须掌握它,因为我经常在文档和博客中看到它,所以我想我会把它传递下去。

【讨论】:

  • 非常感谢您的详细解释。如果我可以说,实现你手中的力量并不总是那么容易。所以不知何故,我试图看看定义组合函数在哪里为数据排序操作带来了一些优势。也许这只是句法,让 api 的消费者或其他东西的合同更容易。那是我试图弄清楚的......无论如何有价值的答案!赞赏
  • 对我的回答很有帮助!我从一个不同的角度开始,将 Kleislis 的构图仅仅作为它们有用的一个例子,但现在你让我意识到它应该是向人们解释它们的主要重点和起点。谢谢! :)
  • 嘿。我们都从不同的背景和角度学习,并以不同的方式呈现信息通常是有用的。你永远不知道什么会帮助它为某人“点击”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
  • 2014-03-08
  • 2018-10-01
  • 2015-12-21
相关资源
最近更新 更多