[Haskell-beginners] Problem combining monads <sigh!>

John M. Dlugosz ngnr63q02 at sneakemail.com
Mon Apr 7 09:06:44 UTC 2014


I think I was looking at the page 
<http://learnyouahaskell.com/for-a-few-monads-more#state> a few paragraphs under the H3 
“The join function”.  It mentions “…we wanted to combine several of them into one, be it 
with <*> or >>=,…”

Now I'm actually quite comfortable with Applicative syntax, and am preferring it in places 
where older texts and examples use monads or fmap etc.  (I look forward to an updated 
standard where Monads are derived from Applicatives.)

	(Aside:  is there a "history" function in GHCi to show the last few commands I typed?)

So, I tried a GHCi example starting with:

λ>(+7) <$> [1,2,3]

λ>[(+7), (*2)] <*> [1,2,3]

no sweat.  Now use >>= to do the same thing:

λ>[(+7), (*2)] >>= [1,2,3]
-- nope
(I'll spare the error messages, which inspired some of the other things to try, some of 
which were just to explore the errors themselves)

λ>[(+7), (*2)] <<= [1,2,3]
-- nope

λ>[(+7), (*2)] =<< [1,2,3]
-- nope

λ>[return (+7), return(*2)] =<< [1,2,3]
-- nope

(Use a single function as a simpler starting point)

λ>(+7) =<< [1,2,3]
-- nope

λ>return (+7) =<< [1,2,3]
-- nope

λ>return (+7) >>= [1,2,3]
-- nope

λ>return [1,2,3]
[1,2,3]
it :: [Integer]
-- just checking

λ>[1,2,3] >>= (+7)
-- nope
λ>[1,2,3] >>= do (+7)
-- nope.  Error messages are talking about
     No instance for (Num [b0]) arising from the literal `1'
so why is it looking inside the monad at one of the values and thinking that itself should 
be a list?

λ>[1,2,3] >>= [(+7)]
-- nope

λ>[1,2,3] >>=  (+7).return
-- nope, but got *two* errors out of that one

λ>[1,2,3] >>=  liftM(+7)
-- nope

λ>[1,2,3] >>=  liftM(+7) ::[Integer]
-- nope

λ>[1,2,3] >>=  liftM(+7) ::Integer
-- nope

λ>[1,2,3] >>=  liftM((+7) :: Integer -> Integer)
-- nope

λ>[[1,2,3]] >>=  liftM((+7) :: Integer -> Integer)
[8,9,10]
it :: [Integer]

Ah, I'm getting somewhere.  But back to the question of why is the element of the list 
(nondeterminism monad) want its own element to be a list too?

λ>return [1,2,3] >>=  liftM((+7) :: Integer -> Integer)
[8,9,10]
it :: [Integer]

Same thing.  But the list is already a monad, not a bare (scalar) value, so what's going on?

λ>[1,2,3] >>= (+7)
-- nope

λ>[1,2,3] >>= map(+7)
-- nope

λ>[1,2,3] >>= liftM(+7)
-- nope  Am I starting to repeat myself?

λ>[1,2,3] >>= liftM(+7) ::[Integer]
-- nope
Give up for the evening.


I wonder if that is a record for how many ways it can be incorrect?  I'm frustrated, 
especially since the Applicative syntax worked so easily.  But the referenced page and 
other texts casually say how they are interchangable.  Urrrgh!

Please enlighten?

—John



More information about the Beginners mailing list