We've seen that the polymorphic type constructor "Maybe a," which maps a type to its maybe-ification, acts as a function from Haskell types to Haskell types.

Now let's picture the collection of Haskell types as a category, where the objects are types, and the morphisms are functions from one type to another. The name given to this category is "Hask."

Note: there are complications that arise from functions which don't terminate. At this early stage in the development, we'll simplify the picture, and limit our consideration to Haskell functions which always terminate (total functions). The category of Haskell types and total Haskell functions is called "Platonic Hask." In this context, when we write Hask will implicitly mean Platonic Hask.

Can we construe Maybe as a functor, where Maybe: Hask -> Hask?

We've already seen that the type constructor "Maybe," which maps the type a to Maybe a, gives the object portion of a functor.

What's left is to define the morphism component of a functor with Maybe, and then to show that this would-be functor satisfies all the functor requirements.

So, suppose "a" and "b" are types, and "f" is a morphism -- which means a function, in the setting of Hask -- from "a" to "b". That is, "f: a -> b".

In order for Maybe to be a functor, we need to define Maybe(f): Maybe(a) -> Maybe(b).

This is called the "lifting" of the function f, by the functor Maybe, to a function Maybe(f).

There's only one thing that f' = Maybe(f) could possibly be.

Choose x in Maybe(a). We must now define f'(x), which must be a value in Maybe(b).

We proceed by case, on the form of the constructor that was used to build x.

Case 1: x = Nothing.

Now there's nothing else besides Nothing that f'(Nothing) could possibly be.

Recap: (Maybe(f))(Nothing) = f'(Nothing) = Nothing.

Case 2: x = Just(y). Now we have to define f'(x) = f'(Just(y)) as some value in Maybe(b).

Now the lowest-hanging-fruit functor in this setting is the one which maps like things to like things. So Just(y) will be expected to map to Just(y'), for some value y' in b.

So, how are we going to come up with a y' in b? Let's look at what we've got to work with, the gives: a value x in a, and a function f: a -> b. Then to get a value y' in b, we simply apply the function f to x. So Just(x) will map to Just(f(x)).

That's it, our hand was forced all along the way.

Recap:

(Maybe(f))(Nothing) = f'(Nothing) = Nothing

(Maybe(f))(x) = f'(x) = Just(f(x))

That's our candidate functor.

To confirm the functor for office, we must next prove that it satisfies its oaths, which are the functor laws.

This is more of a clerical exercise, which we'll take care of in the following appendix.

]]>```
data Maybe a = Nothing | Just a
```

Ok, we have all the conceptual tools required to understand what this means.

A value of type "Maybe int" is either something like "Just 45", or else the constant Nothing.

So it's like the class of integers, plus some special designated null value, called Nothing.

"Just int" is the specific constructor that maps the integer "n" to the value term "Just n" which in turn belongs to the class of values for "Maybe int".

"Nothing" is the constructor that picks out the fixed constant Nothing.

"Maybe" is the polymorphic type constructor that maps type "a" to type "Maybe a".

Question: How are the semantics of Nothing handled, given that the type variable is not a parameter for this constructor? How do we arrive at a different Nothing constructor, for each instance of "Maybe a"?

<END-TALK/OPEN-DISCUSSION>

]]>Note: Talk 1.* is a series of mini-talks which is leading towards the concept of functors in Haskell.

```
data Identity a = MkId a
```

"MkId 45" is a *value*, thought of as an "isomorphic copy" of 45. Think of this simply as a formal term. Using pattern matching, the term can be deconstructed, to extract the stored value, 45.

"MkId int" is a *data constructor*. (aka a value constructor.) This is a function, plain and simple, that maps the integer x to the value "MkId x".

"MkId a" is a polymorphic data constructor, with respect to the type variable a. Think of this as the function which maps each Haskell type a to the data constructor "MkId a". In other words, it is a family of per-type data constructors, parameterized by the type variable a.

Let's digress to another type constructor:

```
data Citrus = Lemon | Lime | Orange
```

Lemon is a data constructor that takes zero arguments. So it stands for a constant value. Similarly for Lime and Orange.

Citrus is a freshly defined type, which is defined by three data constructors. The only way to create a value of type Citrus is through one of its data constructors. The type itself can be thought of as being equal to the set of all values of that type.

(This is the *meaning* behind the statement that Citrus is an enumeration consisting of the constants Lemon, Lime and Orange.)

Now suppose we had:

```
SillyIdentity a = MkId a | OtherConstructor a
```

Now this polymorphic "type SillyIdentity a" is given by two polymorphic data constructors, "MkId a", and "OtherConstructor a".

"SillyIdentity int" is a particular type, which consists of all values of the form "MkId x" or "OtherConstructor x", for integers.

Recall that these values are thought of as formal terms, which can be deconstructed to obtain both the constructor type (MkId/OtherConstructor), and the value encapsulated in the term.

This means that all values are tagged with their constructor information. So, just by looking at a value, we can always reconstruct exactly how it was constructed.

Now let's return to the object at hand:

```
data Identity a = MkId a
```

By now it's pretty clear what "Identity int" means. For this type, there just happens to be a single data constructor.

"Identity int" is a specific type.

"Identity a" is a *polymorphic data type*, with respect to the type variable "a". It's a family of specific types, parameterized by "a".

Abstracting, we can can say that "Identity" means the function which maps each type "a" to the type "Identity a."

"Identity" is a *polymorphic type constructor.*

There's more to the story than that, however, as "Identity" operates not just on the types in Haskell, but also on the functions that go between types. But this is a story for another day, we will talk about how "Identity" works as a *functor*.

<END-TALK/OPEN-DISCUSSION>

]]>