# Functor

The basis of things to come

*[This article was expanded on 2020-04-06.]*

The first place to look for an introduction to any structure is Hackage, which covers `Functor`

pretty well. Consider this article a commentary on that page.

There we are told Functors are:

uniform action over a parameterized type, generalizing the map function on lists.

The class provides a single higher order method for converting the parameter type of the functor.

If the transformer function, `f`

is of type `Foo->Bar`

then `fmap f`

will convert `Baz Foo`

values into `Baz Bar`

values.

Often the `<$>`

operator is used. It is but an alias for `fmap`

.

Functors are really quite primal and I would advise anyone starting out with Haskell prioritising getting used using them, stacks of them. If you have an `IO`

action that returns a `Maybe String`

but you need a `Maybe T.Text`

then this should be quite natural (bearing in mind that, like many useful types, `IO`

and `Maybe`

are functors):

Of course `fmap T.pack`

(in this context) is of type

which is just a function we can apply as an argument to `fmap`

:

and so,

but `fmap`

and `<$>`

are the same function (in the standard `Prelude`

anyway) so this is equivalent to:

[Notice the way that whole explanation of stacked functors took place entirely in the land of types — this is a central feature of Haskell that every Haskell program or fragment has a dual life: a static life in types and a dynamic life at runtime.]

The above pattern is so pervasive that it is worth getting familiar with, especially in an `IO`

context. `f <$> action`

(or `fmap f action`

) applies some arbitrary function `f`

to the output of the `IO`

`action`

.

But this is bur a single pattern. Functors can be applied pretty much anywhere.

## Other Operators

Functor provides some useful auxiliary operators and functions.

### (<$)

is equivalent to this

forcing the output of `s`

to a constant value:

```
-- | uses `getLine` to read a line from stdin and discards it
discardLine :: IO ()
discardLine = () <$ getLine
```

### ($>)

This operator

is the same operator as `<$`

, but with its arguments flipped:

so we could have written above:

```
-- | uses `getLine` to read a line from stdin and discards it
discardLine :: IO ()
discardLine = getLine $> ()
```

### (<&>)

This operator,

is a flipped version of `($>)`

so we can say

```
import Data.Char (toUpper)
-- | read string from stdin, mapping each char to upper case
getUpper :: IO String
getUpper = readLine <&> map toUpper
```

### void

This is just a special case of `<$`

(or `$>`

) that force the output of the functor to the unit type `()`

.

Above, e could have written:

```
-- | uses `getLine` to read a line from stdin and discards it
discardLine :: IO ()
discardLine = void getLine
```

## Best is yet to come

In [the notes for `($)`

on the Hackage `Functor`

page notes the symmetries between the function application operator `($)`

and `(<$>)`

.

This is not accidental and totally in keeping with the way it is used, including the examples at the top of this article.

Just as `($)`

can be used to transform the output of a function, so `(<$>)`

can be used to transform the output of a Functor.

```
import Data.Char (toLower)
import System.Environment (getEnv)
data Env = Env { envLabel :: String }
prjLabel :: Env -> String
getLabel :: String -> IO String
prjLabel env = map toLower $ envLabel env
getLabel nme = map toLower <$> getEnv nme
```

But hold on a minute, aren’t we getting ahead of ourselves, `getEnv`

is an `IO`

, a famous monad, not a Functor? But all monads are applicatives and all applicatives are functors, so monads are functors of course.

Everything we are saying about functors is true of applicatives (and monads), and everything we say about applicatives will be true of monads. This compositional understanding is important to understanding the big picture, and as we can see it provides an accessible place to start.

## Identities

Functors come from abstract algebra and, as we are reminded at the top of the top Functor Hackage page, where they are characterised by the following identities.

That these simple identities (along with those for the other structures) can give rise to all of this is truly a wonderous thing!

*Got an issue with any of this?*
Please share
or drop me a line (see below).