了解Kleisli与`bind`的关系

时间:2015-11-14 20:07:19

标签: 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

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

2 个答案:

答案 0 :(得分:3)

它与(.)($)(或函数应用程序)之间的差异或多或少相似。

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

countEven = length . filter even

或者我能做到

countEven xs = length $ filter even $ xs

这真的是一样的东西,最后编译/内联到同一个东西,但这两个“意味着”不同的东西。

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

说同样事情的不同方式。你绝对可以用另一个来实现一个:

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

答案 1 :(得分:0)

正如贾斯汀说的那样.。您可以将(>=>) plus10 minus5 5重写为return 5 >>= (plus10 >=> plus5),您可以轻松比较两个版本

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

换句话说,如果你想写一个无点版本,你不能只写plus10 >>= minus5,而是需要使用>=>