Haskell programmers work much more rapidly because of this phenomenally high code reuse. Other languages penalize you for using a new library because you must spend a considerable amount of time learning the library's API, reading documentation, and learning library-specific conventions. A proficient Haskeller adopts libraries in minutes because they all share common interfaces derived from category theory.

I'll illustrate this using Haskell's

`Functor`interface, derived from functors in category theory.

#### Maybe Functor

Java programmers must constantly check for null pointers. This forces them to constantly write code like the following:

String s = null; if (null != x) { s = x.toString(); }C programmers have the same problem, where a function might return a special value or null pointer to indicate failure:

FILE *fp = NULL; fp = fopen("poem.txt", "w"); if (fp) { fprintf(fp, "Roses are red\n"); }In Haskell, you model values that might be empty using the following type:

data Maybe a = Just a | Nothing

`Maybe a`denotes something that "maybe" holds a value of type

`a`because there are two ways you can build a value of type

`Maybe a`. Either you provide a value of type

`a`using the

`Just`constructor or you provide no value at all with the

`Nothing`constructor. For example, a map lookup might fail, so the type of Haskell's lookup function is:

lookup :: (Ord k) => k -> Map k a -> Maybe aThis works great except for one problem. All our existing functions that expect arguments of type

`a`will reject arguments of type

`Maybe a`. For example, the following code will not compile:

square :: Int -> Int square x = x ^ 2 four = square (Just 2) -- wrongThis fails to compile because

`square`expects its argument to be of type

`Int`and not

`Maybe Int`, so let's write a helper function to give

`square`a hand by converting

`square`into a function that works on

`Maybe`s. Haskell uses the name

`fmap`for this function:

fmap:: (a -> b) -> Maybe a -> b -- wrong fmap f (Just x) = f xOops! We forgot to cover all possible constructors.

`fmap`'s second argument has type

`Maybe a`, which means that

`fmap`must also accept

`Nothing`for its second argument. If we try to lift our function to operate on a

`Nothing`,

`fmap`will fail with a run-time error:

> fmap square (Just 2) 4 > fmap square Nothing *** Exception: Non-exhaustive patterns in function fmapHmm, it seems that our

`fmap`function can sometimes fail, so why not make its return type use

`Maybe`to encapsulate that failure:

fmap :: (a -> b) -> Maybe a -> Maybe b fmap f (Just x) = Just (f x) fmap f Nothing = NothingMuch better! Now our function handles errors transparently by simply propagating them:

> fmap square (Just 2) Just 4 > fmap square Nothing NothingWe just unwittingly defined our first functor, the

`Maybe`functor. To see why, let's look at the definition of the

`Functor`class:

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

`Maybe`for

`f`then you get the type signature for the

`fmap`function we just derived. Using Haskell terminology,

`Maybe`is an instance of the

`Functor`class. Haskell classes are analagous to C#/Java interfaces, so using their terminology you would say that

`Maybe`implements the

`Functor`interface.

#### Collection Functors

Haskell lists are ordered sets of objects and a Haskell list containing objects of type

`a`is denoted

`[a]`, which is just syntactic sugar for

`[] a`. You can treat

`[]`as a

`Functor`:

instance Functor [] where fmap :: (a -> b) -> [a] -> [b] fmap = mapPython programmers might recognize this is the same as their

`map`function. Just like Python's

`map`,

`fmap`will work on all homogeneous Haskell data structures and generators (a.k.a. iterables in Python) because they all implement the

`Functor`interface:

instance Functor Set where fmap :: (a -> b) -> Set a -> Set b fmap = ... -- implementation elided instance Functor Tree where fmap :: (a -> b) -> Tree a -> Tree b fmap = ... -- implementation elided instance Functor (Map k) where fmap :: (a -> b) -> Map k a -> Map k b fmap = ... -- implementation elidedHaskell differs from C++ and Java in that it does not have a unified collections interface, because many operations on collections are actually instances of more general classes. For example, list concatenation uses

`mappend`from the

`Monoid`class.

Since our

`fmap`function surprisingly works on collections, you might wonder what else it works on.

#### State Functor

Haskell has a dead-simple implementation of state:

-- actually a newtype and I've flipped the output type State s a = s -> (s, a)In other words, a stateful function is one that takes a state

`s`and returns a new state

`s`along with a possible output

`a`. In fact, this is how Haskell handles I/O, except that

`s`is the state of the outside world. Seriously:

type IO a = State RealWorld a -- actually a newtypeAs you might have guessed,

`State s`and

`IO`are functors:

instance Functor (State s) where fmap :: (a -> b) -> State a -> State b fmap f x s = second f (x s) -- a pure function instance Functor IO where fmap :: (a -> b) -> IO a -> IO b fmap f x s = second f (x s) -- no differentI only included the implementations to emphasize that they are ordinary, pure functions and that there is nothing special or magic about how either functor works.

Haskell's

`getLine`function reads a line from standard input and returns the

`String`as that output of type

`a`that I mentioned above. That means its type is:

getLine :: IO String -- i.e. (RealWorld -> (RealWorld, String))Because it is a functor, I can apply a function to its output (the

`String`), before I even run it and it will now return the transformed value when it's finally executed. So if I have a function named

`parseInteger`that converts

`String`s to

`Integer`s, then I can just write:

parseInteger :: String -> Int getInteger :: IO Integer -- i.e. (RealWorld -> (RealWorld, Int)) getInteger = fmap parseInteger getLineVoila! I just created a new function that now reads a line from standard input and returns the parsed

`Integer`. I don't think there is anything equivalent to the generality of

`fmap`in the standard libraries of mainstream languages.

#### Parser Functor

In Haskell, a function that parses

`String`s has the type:

type Parser a = String -> [(a, String)] -- actually a newtypeTo understand the type, it takes a string and returns a list of possible parsed values along with their corresponding unconsumed

`String`s. This is a functor, too, which means that if I have something that parses a list of values and I want to convert the list to a tree, I just write:

convertToList :: [a] -> Tree a parseTree :: Parser [a] <$> = fmap -- an infix operator synonymous with fmap convertToList <$> parseTree :: Parser (Tree a)Convenient! If you squint, the infix version of

`fmap`,

`<$>`, resembles function application. It's almost as if we were applying

`convertToList`directly to

`parseTree`and the

`<$>`makes the type incompatibility just magically go away.

#### Functors

So if you see something resembling

`f a`in a type signature and you guess that

`f`is some sort of functor, chances are you will be right. However, you don't have to guess. You can just fire up

`ghci`and type something like:

> :info Maybe ... instance Functor Maybe -- Defined in Data.Maybe ...... or if

`f`is a type variable in a function's type signature, it will say something like:

functorsForAll :: (Functor f, ...) => ... -> f a -> ...Functors are just the tip of iceberg. Haskell programmers reuse classes like crazy and

`Functor`isn't even the most used class (which would arguably be the

`Monad`class). The typical Haskell programmer reuses a few functions like

`fmap`over and over again to great effect, and once you learn those few functions your Haskell productivity will soar. These functions "just work" and always do the "right thing", yet in a completely type-safe manner.

Equally important, Haskell programmers reason more easily about their programs because they reuse the same concepts over and over again. They can rapidly form a mental model of how a function or library works because everything is assembled from the same set of core primitives derived from category theory.

Haskell classes, like C#/Java interfaces, promote generality and code reuse, but they are much more general and reusable than their mainstream counterparts because they have a strong mathematical foundation in category theory. However, Haskell requires no actual knowledge of category theory to use it.