How to detect a Monad?

后端 未结 4 1197
遇见更好的自我
遇见更好的自我 2021-02-13 04:02

Many of us don\'t have a background on functional programming, and much less on category theory algebra. So let\'s suppose that we need and therefore create a generic type like<

4条回答
  •  长情又很酷
    2021-02-13 04:16

    You should be on the lookout if you end up writing any operations that have signatures that look like any of these—or just as importantly, if you have a number of functions that can be refactored to use them:

    ----- Functor -----
    
    -- Apply a one-place function "inside" `MySomething`.
    fmap :: (a -> b) -> MySomething a -> MySomething b
    
    ----- Applicative -----
    
    -- Apply an n-place function to the appropriate number and types of 
    -- `MySomething`s:
    lift :: (a -> ... -> z) -> MySomething a -> ... -> MySomething z
    
    -- Combine multiple `MySomething`s into just one that contains the data of all
    -- them, combined in some way.  It doesn't need to be a pair—it could be any 
    -- record type.
    pair :: MySomething a -> ... -> MySomething z -> MySomething (a, ..., z)
    
    -- Some of your things act like functions, and others like their arguments.
    apply :: MySomething (a -> b) -> MySomething a -> MySomething b
    
    -- You can turn any unadorned value into a `MySomething` parametrized by
    -- the type
    pure :: a -> MySomething a
    
    -- There is some "basic" constant MySomething out of which you can build 
    -- any other one using `fmap`.
    unit :: MySomething ()
    
    ----- Monad -----
    
    bind :: MySomething a -> (a -> MySomething b) -> MySomething b
    join :: MySomething (MySomething a) -> MySomething a
    
    ----- Traversable -----
    
    traverse :: Applicative f => (a -> f b) -> MySomething a -> f (MySomething b)
    sequence :: Applicative f => MySomething (f a) -> f (MySomething a)
    

    Note four things:

    1. Applicative may be less famous than Monad, yet it's a very important and valuable class—arguably the centerpiece of the API! A lot of things that people originally used Monad for actually only require Applicative. It's a good practice not to use Monad if Applicative will do.
    2. Similar remarks could be made of Traversable—a lot of functions that were originally written for Monad (sequence, mapM) in fact only require Traversable + Applicative.
    3. As a consequence of the above, oftentimes the way you'll discover something is a Monad is by first discovering that it's an Applicative and then asking whether it's also a Monad.
    4. Don't forget the laws—they're the authoritative arbiter of what makes it and what doesn't.

提交回复
热议问题