CommonTypeClasses

The main type classes is what I think is the hardest part to understand in Haskell. Its difficult to understand the purpose of each type class e.g. Monads, Applicatives and Functors. And its difficult to understand why the laws of each type class should apply.

There are many good references which explain this much better than I do here. This is just for me …

Problem 1: I want to apply a function of arbitrary length on values that have a context. In this example the arbitrary length of the function `add3`

is 3.

```
let add3 = \a b c -> a + b + c
p0 = Just 1
p1 = Just 2
p2 = Just 3
:t add3
add3 :: Integer -> Integer -> Integer -> Integer
```

If I had pure values the calculation would be trivial.

```
add3 1 2 3
=> 6
```

`Just 1`

is a `Maybe`

type class which is an instance of `Functor`

, `Applicative`

and `Monad`

.

So lets try to perform the calculation using the `Functor`

type class. `Functor`

has the ability to map a function (`fmap`

) on a single value in an context and return the result in the same context.

```
:t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
:t fmap add3 (Just 1)
fmap add3 (Just 1) :: Maybe (Integer -> Integer -> Integer)
```

So `fmap`

is able to partially apply `add3`

to `1`

and embed it in a `Maybe`

context.

`fmap`

takes a pure functions. So to be able to apply the partial function to next argument (`Just 2`

) we would need to extract the pure function from the `Maybe`

context again. This could of course be done.

`let fromJust (Just x) = x`

So this could be used to apply `fmap`

again

```
:t fmap (fromJust $ fmap add3 (Just 1)) (Just 2)
fmap (fromJust $ fmap add3 (Just 1)) (Just 2) :: Maybe (Integer -> Integer)
```

And again

```
fmap (getPure $ fmap (getPure $ fmap add3 (Just 1)) (Just 2)) (Just 3)
Just 6
```

But, this isn’t especially readable. `Applicative`

have a much more convenient function which would simplify things radically. `<*>`

does specifically what we want. It takes a function in a context and applies that to a value in a context.

```
:t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
```

Because the partially applied function we got from the first application of `fmap`

on the `Maybe`

value is in a context this can be used directly.

```
:t fmap add3 (Just 1) <*> (Just 2)
fmap add3 (Just 1) <*> (Just 2) :: Maybe (Integer -> Integer)
```

This returns the second partial application of `add3`

in a context so it can be used again to finalize the calculation. Note that `<*>`

is left assiciative.

```
fmap add3 (Just 1) <*> (Just 2) <*> (Just 3)
Just 6
```

This is much simpler than alternating between `fromJust`

and `fmap`

to get to the result!

`Applicative`

also provides a function to put a primitive value in context called `pure`

.

```
:t pure
pure :: Applicative f => a -> f a
```

So if we use `pure`

to put `add3`

in contect we have an alternative way to perform the calculation.

```
pure add3 <*> (Just 1) <*> (Just 2) <*> (Just 3)
Just 6
```

The fact that `pure add3 <*> (Just 1) = fmap add3 (Just 1)`

is actually one of the laws of applicative functors.

`pure f <*> x = fmap f x`

Because `pure f <*> x`

is so commonly used, a helper function is defined which does both these operation in one go.

```
:t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<$>) f x = pure f <*> x -- OR
(<$>) f x = fmap f x
:t add3 <$> (Just 1)
add3 <$> (Just 1) :: Maybe (Integer -> Integer -> Integer)
:t fmap add3 (Just 1)
fmap add3 (Just 1) :: Maybe (Integer -> Integer -> Integer)
:t pure add3 <*> (Just 1)
pure add3 <*> (Just 1) :: Maybe (Integer -> Integer -> Integer)
```

So the same expression can be written in a even more readable way.

```
add3 <$> (Just 1) <*> (Just 2) <*> (Just 3)
Just 6
```

From what we have seen, using Applicatives we can perform a set of computations in a pre-defined order i.e. the partial application of `add3`

on each of the values in context (from left to right). What if the sequence of operations isn’t known from the beginning i.e. if one of the computations return different results (e.g. because its impure).

Instead of the pre-defined values (like `Just 1`

), I have defined an IO operation (`getNum`

) that takes a string as input from the user and convert that string to an integers. Lets try it.

```
getNum
1
1
getNum
text
*** Exception: Prelude.read: no parse
```

Yes, it chokes if I dont enter an integer.

So how is `getNum`

defined? `getLine`

takes user input and return `IO String`

. `IO String`

is a monad type class to encapsulate IO in a pure context. An `IO String`

value is non-determined until the program executes and the actual value is retrieved from the user.

```
:t getLine
getLine :: IO String
```

`getNum`

should return the number and not the string so I need to convert the input. The pure function `read`

does that for us. Read convert a sting to any type `a`

. To make it understand what to convert to we need to supply a type signature for the expected result.

```
:t read
read :: Read a => String -> a
:t (read :: String -> Integer)
(read :: String -> Integer) :: String -> Integer
```

A monad type class is similar to applicatives in that it holds a value in a context. The different context is specified by its specific set of functions and laws that must apply for every monad. Functors, Applicatives and Monads are all related. All Monads are Applicatives which in turn are Functors.

One important function of the monad class is the `bind`

function (`>>=`

).

```
:t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
```

As you can see it is quite similar to `fmap`

and `<*>`

. While `fmap`

takes a pure function applied to a value with context and <*> takes the same function*in a context* and applies to the same value in context, `>>=`

takes a function which takes a pure value and return the result in a context and apply that function to a value with a context. The order of arguments is also reversed.

So how do we create a function that takes a pure value and return that value in a context. Using `pure`

would be one way.

```
let f a = pure a
Prelude Control.Applicative> :t f
f :: Applicative f => a -> f a
```

Monad type class define `return`

which is synonymous to `pure`

.

```
:t return
return :: Monad m => a -> m a
```

So, if we use `getLine`

it will generate a string in a IO context. If we define a function that takes that pure string value, convert it to an integer and return that integer in a new IO context, we should be able to use `>>=`

to bind these two operations together as a single computation.

```
:t (return . (read :: String -> Integer))
(return . (read :: String -> Integer)) :: Monad m => String -> m Integer
let getNum = getLine >>= (return . (read :: String -> Integer))
:t getNum
getNum :: IO Integer
```

`getNum`

is similar to `Just 1`

as they are both values in a context, however somewhat different contexts.

Lets see how the IO monad works as applicatives.

```
Prelude Control.Applicative> add3 <$> getNum <*> getNum <*> getNum
1
2
3
6
```

Yes, that works as expected.

This is the essence on how impure functions can be mixed with pure functions. It is still the pure `add3`

functions that we use to calculate the sum of the impure results from `getNum`

. It is `getNum`

that must be validated with extra concern (as it is impure), not the whole composed operation.

So far we assume that user always input is 3 integers and nothing else. What if we were to execute completely different results depending on user input. This *is* not very uncommon (and trivial in an imperative language).

Problem 2: I want collect numbers from the user and sum them, until user enter `q`

This impossible to do with applicatives or functors. Using monads it is possible.

The bind function can return different monadic values depending on the value entering the monadic function or the result of the computation itself.

To be able do perform IO computations the monadic values must be of type `IO a`

. The result of this computation is a sum of integers, so the monadic type should hold the sum in an IO context (`IO Integer`

).

Hence, the monadic computation takes the current sum as input and retrieves a new integer from the user. If user enter `q`

the current sum is returned. If a number is entered, current monadic function is bound to itself with the updated sum as input.

```
getNum :: Integer -> IO Integer
getNum acc = do
s <- getLine
if s == "q" then return acc
else getNum $ acc + (read s :: Integer)
```

The main function is trivial. We just call `getNum`

with sum set to 0 and print the result. Note that `getNum 0`

will result in an unknown set of computations.

```
main = do
res <- getNum 0
putStrLn $ show res
```

To see how `do`

maps to the bind `(>>=)`

function we can de-sugar the main function.

`main = getNum 0 >>= (\res -> putStrLn $ show res)`

This composition of `getNum`

depending on user input, cannot be implemented using applicatives. With applicatives the execution of each computation is ordered, but the number of computations must be explicit by the code. With monadic values and the composition using bind this is not necessary.

The result of the computation can be a sum of 0 or more computations depending on user input.

```
./sum_test
1
2
3
q
6
```

```
> :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
> (+1) <$> Just 1
Just 2
> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
> Just (+1) <*> Just 1
Just 2
> [(+1),(+2)] <*> [1,2]
[2,3,3,4]
> (+) <$> [1,2] <*> [10,20]
[11,21,12,22]
> fmap (+) [1,2] <*> [10,20]
[11,21,12,22]
instance Applicative ((->) r) where
pure x = (\_ -> x)
f <*> g = \x -> f x (g x)
let ap f g = \x -> f x (g x)
> :t ap
ap :: (t2 -> t1 -> t) -> (t2 -> t1) -> t2 -> t
> ap (+) (+2) 1
4
```

Note `f`

in `ap f g`

takes two parameters and g one. So the calculation is

```
(+) 1 ((+) 2 1) = 4
> replicate 3 1 >>= replicate 2
[1,1,1,1,1,1]
> [1] >>= replicate 3 >>= replicate 2
[1,1,1,1,1,1]
```

I don’t understand where this is defined. There is a pattern match fail in the second example. Why exception in the translated case?

```
> do { [a] <- Just [2]; return a } :: Maybe Int
Just 2
> do { [a] <- Just [1,2]; return a } :: Maybe Int
Nothing
> Just [1] >>= (\[a] -> return a) :: Maybe Int
Just 1
> Just [1,2] >>= (\[a] -> return a) :: Maybe Int
*** Exception: <interactive>:104:17-32: Non-exhaustive patterns in lambda
```