7

My understanding is that the difference between map and fmap is that the latter can return a function?

I'm studying the functors section of this http://learnyouahaskell.com and some of the explanation is a bit unclear.

Map and fmap behave identically in the following:

let exMap = map (+1) [1..5]
let exFMap = fmap (+1) [1..5]

What is a good example of an fmap returning a function?

asked Sep 29, 2016 at 8:52

3 Answers 3

12

No, the difference is that fmap applies to any functor. For instance:

readLine :: IO String -- read a line
fmap length readLine :: IO Int -- read a line and count its length
Just 4 :: Maybe Int
fmap (+10) (Just 4) :: Maybe Int -- apply (+10) underneath Just
 -- returns (Just 14)

map turns a -> b into a function [] a -> [] b (usually written as [a] -> [b]).

fmap turns a -> b into a function f a -> f bfor any functor f, not only for f = []. The examples above chose f = IO and f = Maybe.

answered Sep 29, 2016 at 9:05
Sign up to request clarification or add additional context in comments.

3 Comments

Could you take this a step further and differentiate, in simple terms, how functors differ from applicative functors?
If you have a->b and f a, when f is a functor, you can get f b using fmap. However, if you have f (a->b) and f a, you can not get f b: the function is wrapped underneath f and there's no way to make it interact with its argument. Applicative functors instead define an additional operation <*> allowing for that.
One available functor is "reader` which indeed relates to functions, but now may not be the best stage to learn about it.
7

It would help to look at the type signatures for each function, let's start with the map function you are looking at:

map :: (a -> b) -> [a] -> [b]

As you can see, this map function operates on lists. Logically however, there are many data structures which can be mapped over. Here are some other possible maps:

map :: (a -> b) -> Map k a -> Map k b
map :: (a -> b) -> Maybe a -> Maybe b
map :: (a -> b) -> IO a -> IO b

This is just the tip of the iceberg, many things can be mapped!

In languages that don't support type classes, this could be the world as you know it. There are simply many map functions and you have to qualify them with an appropriate module type to distinguish which map you actually mean. Not so in Haskell!

Now let's look at fmap:

fmap :: Functor f => (a -> b) -> f a -> f b

This function has exactly the same form as those shown above but works on anything which is a functor.

Functor is defined like this:

class Functor f where
 fmap :: (a -> b) -> f a -> f b
 (<$) :: a -> f b -> f a
 (<$) = fmap . const

Hopefully this makes it obvious that a functor is simply something that supports being mapped over.

Therefore fmap is general, while map is specific.

answered Sep 29, 2016 at 9:07

3 Comments

You should clarify that you can't fmap over Text or ByteString, though, since they are not functors.
@chi I'll just replace them with better examples.
@TheInnerLight could you give an example of applying this to a binary tree of type data Tree a = Empty | Node a (Tree a) (Tree a)?
3

fmap is more general than map - and indeed for lists there is no difference - here you have map == fmap.

Let us begin with the definition of fmap

class Functor f where
 fmap :: (a -> b) -> (f a -> f b)

this essentially says you can turn a simple function into a function that transforms containers into containers of the same shape but different elements.

instance Functor [] where
 fmap = map
instance Functor Maybe where
 fmap _ Nothing = Nothing
 fmap f (Just something) = Just (f something)

there are many more, I think almost every container with a single type parameter can be a functor

As an exercise you can try to define an instance for

data Tree a = Tree a [a]

for the usage of fmap see @chi's answer.

answered Sep 29, 2016 at 9:09

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.