monad绑定(>> =)运算符更接近函数组合(链接)还是函数应用程序? [英] Is monad bind (>>=) operator closer to function composition (chaining) or function application?

查看:142
本文介绍了monad绑定(>> =)运算符更接近函数组合(链接)还是函数应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在很多文章中,我已经读过monad >> = 操作符是表示函数组合的一种方法。但对我来说,它更接近某种高级函数应用程序。

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

对于构图,我们有
<$ p $ (。)::(b - > c) - > (a - > b) - > a - > c
(> =>):: Monad m => (a - > m b) - > (b→m c)→> a - > mc

请澄清。

解决很明显,>> = 不是表示函数组合的方法。 函数组合只需使用完成。然而,我认为你读过的任何文章都不意味着这一点。

他们的意思是升级函数组合直接与一元函数一起工作,即 a - >的函数。 m b 。这些功能的技术术语是Kleisli箭头,实际上它们可以由< =< / code>或>组成; => 。 (或者,您可以使用 类别实例,那么你也可以用>>> .org / Point-free>普通函数的无点定义常常令人困惑。幸运的是,Haskell允许我们以更熟悉的风格来表达函数,这些函数专注于函数的结果,而函数本身就是抽象态射体。它完成了lambda抽象:而不是

  q = h。 G 。 f 

您可以写出

  q =(\ x  - >(\ y  - >(\ z  - > hz)(gy))(fx))

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

  qx = let y = fx 
z = gy
in hz

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

  q = \x  - > (\y->(\z-> hz)$ gy)$ fx 

根据Kleisli箭头,这意味着代替

  q = h <=< g< =< f 

您写下

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

当然翻转后的操作符或语法糖看起来更好:

  qx = do y < -  fx 
z < - gy
hz

因此,实际上, = < c <= < = < / code>> $ 就是。把它称为组合运算符仍然有意义的原因是,除了应用于值之外,>> = 运算符也会执行非平凡位Kleisli箭头组成,其功能组成不需要:加入monadic层。






其原因是 Hask 笛卡尔封闭类别,in特别是高分类。在这样的类别中,广义上讲,箭头可以通过将其所有结果的集合应用于简单参数值来定义。 ; @adamse注释 let 对于lambda抽象来说并不是真正的语法糖。在递归定义的情况下,这是非常重要的,你不能直接用lambda来写。但在这样的简单情况下, let 的行为就像lambda表达式的语法糖一样,就像 do notation是语法糖为lambdas和>> = 。 (顺便说一句,有一个扩展允许递归甚至在 do >符号中。它通过使用定点组合器规避了lambda限制。)

In many articles I have read that monad >>= operator is a way to represent function composition. But for me it is closer to some kind of advanced function application

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

For composition we have

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

Please clarify.

解决方案

Clearly, >>= is not a way to represent function composition. Function composition is simply done with .. However, I don't think any of the articles you've read meant this, either.

What they meant was “upgrading” function composition to work directly with “monadic functions”, i.e. functions of the form a -> m b. The technical term for such functions is Kleisli arrows, and indeed they can be composed with <=< or >=>. (Alternatively, you can use the Category instance, then you can also compose them with . or >>>.)

However, talking about arrows / categories tends to be confusing especially to beginners, just like point-free definitions of ordinary functions are often confusing. Luckily, Haskell allows us to express functions also in a more familiar style that focuses on the results of functions, rather the functions themselves as abstract morphisms. It's done with lambda abstraction: instead of

q = h . g . f

you may write

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

...of course the preferred style would be (this being only syntactic sugar for lambda abstraction!)

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

Note how, in the lambda expression, basically composition was replaced by application:

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

Adapted to Kleisli arrows, this means instead of

q = h <=< g <=< f

you write

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

which again looks of course much nicer with flipped operators or syntactic sugar:

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

So, indeed, =<< is to <=< like $ is to .. The reason it still makes sense to call it a composition operator is that, apart from “applying to values”, the >>= operator also does the nontrivial bit about Kleisli arrow composition, which function composition doesn't need: joining the monadic layers.


The reason this works is that Hask is a cartesian closed category, in particular a well-pointed category. In such a category, arrows can, broadly speaking, be defined by the collection of all their results when applied to simple argument values.

@adamse remarks that let is not really syntactic sugar for lambda abstraction. This is particularly relevant in case of recursive definitions, which you can't directly write with a lambda. But in simple cases like this here, let does behave like syntactic sugar for lambdas, just like do notation is syntactic sugar for lambdas and >>=. (BTW, there's an extension which allows recursion even in do notation... it circumvents the lambda-restriction by using fixed-point combinators.)

这篇关于monad绑定(&gt;&gt; =)运算符更接近函数组合(链接)还是函数应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆