[Haskell-beginners] Understanding Monads: Help with 20 Intermediate Haskell Exercises
tushar4r at gmail.com
Wed May 18 10:24:59 UTC 2016
In order to wrap my head around Applicatives and Monads, I started doing
The main class being used for the questions is:
class Misty m where banana :: (a -> m b) -> m a -> m b unicorn :: a
-> m a furry' :: (a -> b) -> m a -> m b
Question #13 asks to create the following function:
apple :: (Misty m) => m a -> m (a -> b) -> m b
After thinking for around an hour for this, I could not crack it and tried
looking at other people's solutions, two of which are:
apple = banana . flip furry'
apple ma mab = banana (\ab -> furry' ab ma) mab
I also tried hoogle to see what this function is in the real world, and the
underlying implementation in the source code. Turns out, one of the
applicatives uses this flip technique (monads use a different one):
(<**>) = liftA2 (flip ($))
Although the code compiles with the solutions, I am still not able to wrap my
head around them.
For instance, from what I understand from composition, the output of
becomes the input of the next one. But the input and outputs of these
banana :: Misty m => (a -> m b) -> m a -> m b
flip furry' :: Misty m => m a -> (a -> b) -> m b
banana . flip furry' :: Misty m => m a -> m (a -> b) -> m b
I am thinking that the entire `(a -> b) -> m b` in flip furry' is
being sent to banana
as the first argument: (a -> m b), but what happens after that?
In the second solution, the types pass, i.e. the lambda is basically
furry' which has the type
a -> ... -> m b, exactly what is needed in the call to banana. But
where will it get the
function ab? And how will banana work with the second argument? The
definition in the
class requires it to be `m a`, but here we are passing it `m a -> m b`.
Sorry for such a long post, but I want to understand this wizardry .
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Beginners