Unfortunately you are running in to strange behavior due to a lack of parenthesis. First of all, let's see what your original expression actually is:

fmap (\x -> x) Just 2 = (fmap (\x -> x) Just) 2

So you can see that you are actually fmaping over Just, rather than Just 2. What does this mean? Well, let's ask GHC:

:t fmap _ Just
    Found hole `_' with type: Maybe a -> b

That is, when you try and fmap over the function Just, we have to provide a function that expects a Maybe a, rather than an a. In your first case, your providing the identity function, which fits the required type as Maybe a -> Maybe a. However, in your second example, you are trying to provide apply the (+ 2) function to a Maybe a value (because x :: Maybe a). You cannot in general add numbers to Maybe a, hence the error message.

Your final expression works because $ is effectively providing parenthesis:

fmap (\x -> x + 2) $ Just 2 = fmap (\x -> x + 2) (Just 2)

The precedence of application in Haskell can be confusing at the start - I suggest liberally using parenthesis, and then using HLint to remove the ones that you don't need. Eventually, you'll build up the necessary intuition.

Hope this helps,
- Ollie 

On Mon, Apr 27, 2015 at 11:02 AM, Shishir Srivastava <shishir.srivastava@gmail.com> wrote:
Hi, 

Please can someone explain why these two expression behave differently - 

----
fmap (\x -> x) Just 2
Just 2

-----
fmap (\x -> x+2) Just 2

No instance for (Num (Maybe a0)) arising from a use of `it'
In a stmt of an interactive GHCi command: print it

----
The first expression evaluates fine whereas the second one fails. However if I do - 
----

fmap (\x -> x+2) $ Just 2
Just 4
----

Then the second expression also returns the Maybe value. Why is $ needed in second expression but not in the first one ?

Thanks,
Shishir 


_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners