haskell - 了解 Kleisli 与 `bind`

标签 haskell

我试图了解 Kleisli(即 >=>)通过 bind (>>=) 提供的内容。

分别查看他们的bindKlesli签名:

λ: :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b

λ: :t (>=>)
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c

然后是这个例子:

λ: let plus10 = \x -> return (x + 10)
λ: let minus5 = \x -> return (x - 5)

我可以使用任一函数调用:

λ: return 5 >>= plus10 >>= minus5
10

λ: (>=>) plus10 minus5 5
10

当然,这是一个简单的例子。但是,Kleisli 相对于 bind 的重要性是什么?通过查看它们的函数定义,我想知道是否每个 Kleisli 函数用法都可以使用 bind 重写。

最佳答案

它或多或少类似于 (.)($) (或函数应用程序)之间的区别。

例如,如果我想计算列表中偶数的数量,我可以这样做:

countEven = length . filter even

或者我也可以

countEven xs = length $ filter even $ xs

这确实是同一件事,并且最终编译/内联到同一件事,但这两个“意味着”不同的事情。

第一个表示“countEven 是偶数过滤列表的长度”。第二个说,“要获取此列表中的偶数数量,请使用 filter Even 对其进行过滤,然后将 length 应用于结果”。

同一件事的不同说法。您绝对可以根据另一个来实现其中一个:

f . g = \x -> f $ g $ x

关于haskell - 了解 Kleisli 与 `bind`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33712782/

相关文章:

通过多行模式匹配的函数声明

Haskell 随机吐出错误的数字

haskell - 在多行 block 中设置 GHCi 提示

multithreading - IORef 和 MVar 有什么区别?

haskell - 共享由 monad Action 计算的信息

Haskell ByteStrings - 最终将大文件加载到内存中

java - 使用 Java ProcessBuilder : Why does hGetLine only return when I close outputStream? 运行 haskell 可执行文件

haskell - 使用列表理解来构建函数

haskell - 如何进行泛化?

Haskell:这个函数的类型是什么?