**La typeclass** `Functor`

So far, we’ve encountered a lot of the typeclasses in the standard library. We’ve played with ** Ord**, which is for stuff that can be ordered. We’ve palled around with

**, which is for things that can be equated. We’ve seen**

`Eq`

**, which presents an interface for types whose values can be displayed as strings. Our good friend**

`Show`

**is there whenever we need to convert a string to a value of some type. And now, we’re going to take a look at the**

`Read`

**typeclass, which is basically for things that can be mapped over. You’re probably thinking about lists now, since mapping over lists is such a dominant idiom in Haskell. And you’re right, the list type is part of the**

`Functor`

**typeclass.**

`Functor`

What better way to get to know the ** Functor** typeclass than to see how it’s implemented? Let’s take a peek.

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

Alright. We see that it defines one function, ** fmap**, and doesn’t provide any default implementation for it. The type of

**is interesting. In the definitions of typeclasses so far, the type variable that played the role of the type in the typeclass was a concrete type, like the a in**

`fmap`

**. But now, the**

`(==) :: (Eq a) => a -> a -> Bool`

**is not a concrete type (a type that a value can hold, like**

`f`

**,**

`Int`

**or**

`Bool`

**), but a type constructor that takes one type parameter. A quick refresher example:**

`Maybe String`

**is a concrete type, but**

`Maybe Int`

**is a type constructor that takes one type as the parameter. Anyway, we see that**

`Maybe`

**takes a function from one type to another and a functor applied with one type and returns a functor applied with another type.**

`fmap`

If this sounds a bit confusing, don’t worry. All will be revealed soon when we check out a few examples. Hmm, this type declaration for ** fmap** reminds me of something. If you don’t know what the type signature of

**is, it’s:**

`map`

**.**

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

Ah, interesting! It takes a function from one type to another and a list of one type and returns a list of another type. My friends, I think we have ourselves a functor! In fact, ** map** is just a

**that works only on lists. Here’s how the list is an instance of the**

`fmap`

**typeclass.**

`Functor`

**instance Functor [] where
fmap = map**

That’s it! Notice how we didn’t write ** instance Functor [a] where**, because from

**, we see that the**

`fmap :: (a -> b) -> f a -> f b`

**has to be a type constructor that takes one type.**

`f`

**is already a concrete type (of a list with any type inside it), while**

`[a]`

**is a type constructor that takes one type and can produce types such as**

`[]`

**,**

`[Int]`

**or even**

`[String]`

**.**

`[[String]]`

Since for lists, ** fmap** is just

**, we get the same results when using them on lists.**

`map`

`Prelude> `**:l fmap**
[1 of 1] Compiling Main ( fmap.hs, interpreted )
Ok, modules loaded: Main.
*Main> **fmap (*2) [1..3]**
:13:1: error:
Ambiguous occurrence ‘fmap’
It could refer to either ‘Prelude.fmap’,
imported from ‘Prelude’ at fmap.hs:1:1
(and originally defined in ‘GHC.Base’)
or ‘Main.fmap’, defined at fmap.hs:2:3
*Main> **Prelude.fmap (*2) [1..3]**
[2,4,6]
*Main> **map (*2) [1..3]**
[2,4,6]

~~ Forse ~~ ho pasticciato troppo; il file ** fmap.hs** contiene il codice che definisce

**; funziona ma c’è l’ambiguità che rende necessaria la precisazione.**

`class Functor f`

What happens when we ** map** or

**over an empty list? Well, of course, we get an empty list. It just turns an empty list of type**

`fmap`

**into an empty list of type**

`[a]`

**.**

`[b]`

Types that can act like a box can be functors. You can think of a list as a box that has an infinite amount of little compartments and they can all be empty, one can be full and the others empty or a number of them can be full. So, what else has the properties of being like a box? For one, the ** Maybe a** type. In a way, it’s like a box that can either hold nothing, in which case it has the value of

**, or it can hold one item, like**

`Nothing`

**, in which case it has a value of**

`"HAHA"`

**. Here’s how**

`Just "HAHA"`

**is a functor.**

`Maybe`

**instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing**

Again, notice how we wrote instance ** Functor Maybe where** instead of instance

**, like we did when we were dealing with**

`Functor (Maybe m) where`

**and**

`Maybe`

**.**

`YesNo`

**wants a type constructor that takes one type and not a concrete type. If you mentally replace the**

`Functor`

**with**

`fs`

**s,**

`Maybe`

**acts like a**

`fmap`

**for this particular type, which looks OK. But if you replace**

`(a -> b) -> Maybe a -> Maybe b`

**with**

`f`

**, then it would seem to act like a**

`(Maybe m)`

**, which doesn’t make any damn sense because**

`(a -> b) -> Maybe m a -> Maybe m b`

**takes just one type parameter.**

`Maybe`

Anyway, the ** fmap** implementation is pretty simple. If it’s an empty value of

**, then just return a**

`Nothing`

**. If we map over an empty box, we get an empty box. It makes sense. Just like if we map over an empty list, we get back an empty list. If it’s not an empty value, but rather a single value packed up in a**

`Nothing`

**, then we apply the function on the contents of the**

`Just`

**.**

`Just`

`*Main> `**Prelude.fmap (++ " HEY GUYS IM INSIDE THE JUST") (Just "Something serious.")**
Just "Something serious. HEY GUYS IM INSIDE THE JUST"
*Main> **Prelude.fmap (++ " HEY GUYS IM INSIDE THE JUST") Nothing**
Nothing
*Main> **Prelude.fmap (*2) (Just 200)**
Just 400
*Main> **Prelude.fmap (*2) Nothing**
Nothing

Another thing that can be mapped over and made an instance of ** Functor** is our

**type. It can be thought of as a box in a way (holds several or no values) and the**

`Tree a `

**type constructor takes exactly one type parameter. If you look at**

`Tree`

**as if it were a function made only for**

`fmap`

**, its type signature would look like**

`Tree`

**. We’re going to use recursion on this one. Mapping over an empty tree will produce an empty tree. Mapping over a non-empty tree will be a tree consisting of our function applied to the root value and its left and right sub-trees will be the previous sub-trees, only our function will be mapped over them.**

`(a -> b) -> Tree a -> Tree b`

**instance Functor Tree where
fmap f EmptyTree = EmptyTree
fmap f (Node x leftsub rightsub) = Node (f x) (fmap f leftsub) (fmap f rightsub)**

Non mi va di ricaricare ** Tree** da un post precedente; questa volta mi fido e copio.

`ghci> `**fmap (*2) EmptyTree**
EmptyTree
ghci> **fmap (*4) (foldr treeInsert EmptyTree [5,7,3,2,1,7])**
Node 28 (Node 4 EmptyTree (Node 8 EmptyTree (Node 12 EmptyTree (Node 20 EmptyTree EmptyTree)))) EmptyTree

Nice! Now how about ** Either a b**? Can this be made a functor? The

**typeclass wants a type constructor that takes only one type parameter but**

`Functor`

**takes two. Hmmm! I know, we’ll partially apply**

`Either`

**by feeding it only one parameter so that it has one free parameter. Here’s how**

`Either`

**is a functor in the standard libraries:**

`Either a`

**instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x**

Well well, what did we do here? You can see how we made ** Either a** an instance instead of just

**. That’s because**

`Either`

**is a type constructor that takes one parameter, whereas**

`Either a`

**takes two. If**

`Either`

**was specifically for**

`fmap`

**, the type signature would then be**

`Either a`

**because that’s the same as**

`(b -> c) -> Either a b -> Either a c`

**. In the implementation, we mapped in the case of a**

`(b -> c) -> (Either a) b -> (Either a) c`

**value constructor, but we didn’t in the case of a**

`Right`

**. Why is that? Well, if we look back at how the**

`Left`

**type is defined, it’s kind of like:**

`Either a b`

**data Either a b = Left a | Right b**

Well, if we wanted to map one function over both of them, ** a** and

**would have to be the same type. I mean, if we tried to map a function that takes a string and returns a string and the**

`b`

**was a string but the**

`b`

**was a number, that wouldn’t really work out. Also, from seeing what fmap’s type would be if it operated only on**

`a`

**values, we see that the first parameter has to remain the same while the second one can change and the first parameter is actualized by the**

`Either`

**value constructor.**

`Left`

This also goes nicely with our box analogy if we think of the ** Left** part as sort of an empty box with an error message written on the side telling us why it’s empty.

Maps from ** Data.Map** can also be made a functor because they hold values (or not!). In the case of

**,**

`Map k v`

**will map a function**

`fmap`

**over a map of type**

`v -> v'`

**and return a map of type**

`Map k v`

**.**

`Map k v'`

Note, the ** '** has no special meaning in types just like it doesn’t have special meaning when naming values. It’s used to denote things that are similar, only slightly changed.

Try figuring out how ** Map k** is made an instance of

**by yourself!**

`Functor`

With the ** Functor** typeclass, we’ve seen how typeclasses can represent pretty cool higher-order concepts. We’ve also had some more practice with partially applying types and making instances. In one of the next chapters, we’ll also take a look at some laws that apply for functors.

Just one more thing! Functors should obey some laws so that they may have some properties that we can depend on and not think about too much. If we use ** fmap (+1)** over the list

**, we expect the result to be**

`[1,2,3,4]`

**and not its reverse,**

`[2,3,4,5]`

**. If we use fmap**

`[5,4,3,2]`

**(the identity function, which just returns its parameter) over some list, we expect to get back the same list as a result. For example, if we gave the wrong functor instance to our**

`(\a -> a)`

**type, using**

`Tree`

**over a tree where the left sub-tree of a node only has elements that are smaller than the node and the right sub-tree only has nodes that are larger than the node might produce a tree where that’s not the case. We’ll go over the functor laws in more detail in one of the next chapters [prossimamente].**

`fmap`

🤩

## Trackback

[…] da qui, copio […]

[…] redux We’ve already talked about functors in their own little section [qui]. If you haven’t read it yet, you should probably give it a glance right now, or maybe later […]