monad绑定(>> =)运算符是否更接近函数组合(链接)或函数应用程序?

时间:2015-12-31 11:29:00

标签: haskell functional-programming bind monads category-theory

在许多文章中我都读到monad >>=运算符是一种表示函数组合的方法。但对我来说,它更接近某种高级功能应用

($)   :: (a -> b) -> a -> b
(>>=) :: Monad m => m a -> (a -> m b) -> m b

我们有作文

(.)   :: (b -> c) -> (a -> b) -> a -> c
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c

请澄清。

2 个答案:

答案 0 :(得分:16)

显然,>>=不是表示功能组合的方法。使用.完成功能组合。但是,我不认为你读过的任何文章都是这个。

他们的意思是“升级”功能组合以直接使用“monadic functions”,即a -> m b形式的功能。这些函数的技术术语是 Kleisli箭头,实际上它们可以由<=<>=>组成。 (或者,您可以使用Category instance,然后您也可以使用.>>>撰写它们。)

然而,谈论箭头/类别往往会让初学者感到困惑,就像普通函数的point-free definitions常常令人困惑一样。幸运的是,Haskell允许我们以更熟悉的方式表达函数,这些函数侧重于函数的结果,而不是函数本身作为抽象态射。它完成了lambda抽象:而不是

q = h . g . f
你可以写

q = (\x -> (\y -> (\z -> h z) (g y)) (f x))

...当然首选的样式是 (这只是lambda抽象的语法糖!)

q x = let y = f x
          z = g y
      in h z

请注意,在lambda表达式中,基本上组合被应用程序替换:

q = \x -> (\y -> (\z -> h z) $ g y) $ f x

适用于Kleisli箭头,这意味着代替

q = h <=< g <=< f
你写了

q = \x -> (\y -> (\z -> h z) =<< g y) =<< f x

对于翻转操作符或语法糖来说,当然看起来更好:

q x = do y <- f x
         z <- g y
         h z

所以,=<<确实是<=<$就是.>>=。将它称为组合运算符仍然有意义的原因是,除了“应用于值”之外,let运算符还可以完成关于Kleisli箭头组合的重要位置,该函数组合不需要:加入monadic层。

这样做的原因是 Hask cartesian closed category,特别是well-pointed category。在这样的类别中,广义上说,箭头可以在应用于简单参数值时通过其所有结果的集合来定义。

@adamse评论let并不是lambda抽象的语法糖。这在递归定义的情况下尤为重要,您无法直接使用lambda编写。但是在这样的简单情况下,do的行为就像lambdas的语法糖一样,就像>>=符号是lambdas的语法糖和Protocol SuperProtocolTest { var stringOne:String? var stringTwo:String? } 一样。 (顺便说一句,那里有一个允许递归even in do notation的扩展......它通过使用定点组合器来规避lambda限制。)

答案 1 :(得分:10)

就像一个例子,考虑一下:

(g <$>)

所以,其中每一个,(h <*>)(k =<<)(g $)都是某种功能应用程序,被提升为Functor,Applicative Functor或Monad&# 34;上下文&#34 ;. f只是常规函数的常规应用。

使用Functors,函数不会影响整个事物的f组件。它们严格在内部工作,不会影响&#34;包装&#34;

使用Applicatives,函数包含在f'中,该包装与参数(作为应用程序的一部分)相结合,以产生结果的包装。

使用Monads,函数本身现在可以生成包装结果,从包装参数(作为应用程序的一部分)中以某种方式提取它们的参数。

我们可以看到三个运算符作为函数上的某种标记,比如数学家喜欢写f^f*f*(以及Eugenio的原创作品) Moggi (1) (f =<<)正是使用的,表示提升的函数:: f a -> f b)。

当然,通过推广的函数{{1}},我们可以将它们链接起来,因为现在这些类型排成一行。促销是允许合成的。

(1)&#34;计算和monad的概念&#34;,Eugenio Moggi,1991年7月。

所以这个仿函数是神奇地在里面工作&#34; &#34;管道&#34 ;;应用是预先用组件制造的预制管道&#34 ;;我们去的时候,monad正在建设管道网络。举例说明:

enter image description here