# Difference between revisions of "Hask"

The objects of Hask are Haskell types, and the morphisms from objects `A` to `B` are Haskell functions of type `A -> B`. The identity morphism for object `A` is `id :: A`, and the composition of morphisms `f` and `g` is `f . g = \x -> f (g x)`.

## Is Hask even a category?

Consider:

```undef1 = undefined :: a -> b
undef2 = \_ -> undefined
```

Note that these are not the same value:

```seq undef1 () = undefined
seq undef2 () = ()
```

This might be a problem, because `undef1 . id = undef2`. In order to make Hask a category, we define two functions `f` and `g` as the same morphism if `f x = g x` for all `x`. Thus `undef1` and `undef2` are different values, but the same morphism in Hask.

## Hask is not Cartesian closed

Actual Hask does not have sums, products, or an initial object, and `()` is not a terminal object. The Monad identities fail for almost all instances of the Monad class.

Why Hask isn't as nice as you'd thought.
Initial Object Terminal Object Sum Product Product
Type `data Empty` `data () = ()` `data Either a b = Left a | Right b` `data (a,b) = (,) { fst :: a, snd :: b}` `data P a b = P {fstP :: !a, sndP :: !b}`
Requirement There is a unique function

`u :: Empty -> r`

There is a unique function

`u :: r -> ()`

For any functions

`f :: a -> r`
`g :: b -> r`

there is a unique function `u :: Either a b -> r`

such that: `u . Left = f`
`u . Right = g`

For any functions

`f :: r -> a`
`g :: r -> b`

there is a unique function `u :: r -> (a,b)`

such that: `fst . u = f`
`snd . u = g`

For any functions

`f :: r -> a`
`g :: r -> b`

there is a unique function `u :: r -> P a b`

such that: `fstP . u = f`
`sndP . u = g`

Candidate `u1 r = case r of {}` `u1 _ = ()` `u1 (Left a) = f a`

`u1 (Right b) = g b`

`u1 r = (f r,g r)` `u1 r = P (f r) (g r)`
Example failure condition `r ~ ()` `r ~ ()` `r ~ ()`

`f _ = ()`
`g _ = ()`

`r ~ ()`

`f _ = undefined`
`g _ = undefined`

`r ~ ()`

`f _ = ()`
`g _ = undefined`

Alternative u `u2 _ = ()` `u2 _ = undefined` `u2 _ = ()` `u2 _ = undefined`
Difference `u1 undefined = undefined`

`u2 undefined = ()`

`u1 _ = ()`

`u2 _ = undefined`

`u1 undefined = undefined`

`u2 undefined = ()`

`u1 _ = (undefined,undefined)`

`u2 _ = undefined`

`f _ = ()`

`(fstP . u1) _ = undefined`

Result FAIL FAIL FAIL FAIL FAIL