Home > Net >  Haskell writing >>= using >=> Monads
Haskell writing >>= using >=> Monads

Time:02-26

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

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

-- how do you use >=> to write bind?

I am absolutely so confused, I understand how both of these works but I cant even get started.

I tried all the following alternatives:

bind1 a b = (b a)
bind2 a b = (a >=> b)
bind3 a b = (b >=> a)
bind4 a b = (a b)

but every single attempt raises an error. Where can i possibly start on this question?

Since >>= has 2 parameters, and >=> has 3, how can I use >=> to write >>= when there is 1 less parameter?

CodePudding user response:

First I'd suggest renaming the type parameters so the final result matches:

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

Now we have a b -> m c in the first signature and a -> m c in the second; that suggests renaming also a to b:

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

That leaves the main difference as having an extra argument a. But we evidently don't need that, so we might as well specialize it to the information-less type () (or any other single-value type):

(>=>) :: Monad m => (() -> m b) -> (b -> m c) -> (() -> m c)
bind :: Monad m =>         m b  -> (b -> m c) ->        m c

() -> m x is actually isomorphic to m x alone:

addDummyArg :: a -> (() -> a)
addDummyArg c () = c
rmDummyArg :: (() -> a) -> a
rmDummyArg f = f ()

And it's just a matter of using those conversion functions to adapt the functions to each other.

CodePudding user response:

Since >>= has 2 parameters, and >=> has 3, how can I use >=> to write >>= when there is 1 less parameter?

Each function in Haskell has one parameter. You can interpret >=> , as a function that has as first parameter something of type a -> m b and the second something of b -> m c, the a -> m c is the "result" function.

What you here can do is manipulate the first parameter of bind into a function that accepts a parameter, and then provide that parameter, something like:

bind :: Monad m => m a -> (a -> m b) -> m b
bind ma f = (const ma >=> f) undefined

Here with const ma, we thus create a function that takes a parameter we do not care about, then we construct an a -> m c by using >=> and we call it with undefined (or some other value) to produce the m c value.

  • Related