[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