Is monad bind (>>=) operator closer to function composition (chaining) or function application?

前端 未结 2 1465
逝去的感伤
逝去的感伤 2020-11-27 05:49

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

2条回答
  •  余生分开走
    2020-11-27 06:14

    Just as an illustration, consider this:

    ($)                ::   (a -> b) ->   a ->   b
    let g=g in (g  $)  ::                 a ->   b
                g      ::   (a -> b)
                                         _____
    Functor f =>                        /     \
    (<$>)              ::   (a -> b) -> f a -> f b
    let g=g in (g <$>) ::               f a -> f b
                g      ::   (a -> b) 
                           ___________________
    Applicative f =>      /             /     \
    (<*>)              :: f (a -> b) -> f a -> f b
    let h=h in (h <*>) ::               f a -> f b
                h      :: f (a -> b)
                                 _____________
    Monad m =>                  /.------.     \
    (=<<)              :: (a -> m b) -> m a -> m b
    let k=k in (k =<<) ::               m a -> m b
                k      :: (a -> m b)
    

    So yes, each one of those, (g <$>), (h <*>) or (k =<<), is some kind of a function application, promoted into either Functor, Applicative Functor, or a Monad "context". And (g $) is just a regular kind of application of a regular kind of function.

    With Functors, functions have no influence on the f component of the overall thing. They work strictly on the inside and can't influence the "wrapping".

    With Applicatives, the functions come wrapped in an f, which wrapping combines with that of an argument (as part of the application) to produce the wrapping of the result.

    With Monads, functions themselves now produce the wrapped results, pulling their arguments somehow from the wrapped argument (as part of the application).

    We can see the three operators as some kind of a marking on a function, like mathematicians like to write say f' or f^ or f* (and in the original work by Eugenio Moggi(1) f* is exactly what was used, denoting the promoted function (f =<<)).

    And of course, with the promoted functions :: f a -> f b, we get to chain them, because now the types line up. The promotion is what allows the composition.


    (1) "Notions of computation and monads", Eugenio Moggi, July 1991.

    • more about compositionality, with a picture: Monads with Join() instead of Bind()

    So the functor is "magically working inside" "the pipes"; applicative is "prefabricated pipes built from components in advance"; and monads are "building pipe networks as we go". An illustration:

提交回复
热议问题