###### Books / Applied Functional Programming Tutorial / Chapter 6

# Typeclasses - custom and predefined

## Typeclasses

Typeclass is a class of types with a definition of common functions for all instances of that class. Please note that the term “class” here means a mathematical class in the set theory, not an object-oriented class!.

Typeclasses represent a powerful means for polymorphism in a strong static type system. They can be related to interfaces in Java or protocols in Clojure, however, they are more powerful.

### Kinds

In the type theory, a kind is the type of a type constructor or, less commonly, the type of a higher order type operator. A kind system is essentially a simply-typed lambda calculus ‘one level up’ from functions to their types, endowed with a primitive type, denoted `*`

and called ‘type’, which is the kind of any (monomorphic) data type. Simply you can observe this with GHCi and `:kind`

command on various types. For example kind `* -> *`

tells that you need to specify one type argument to create a type with kind `*`

so you can have values of it.

```
Prelude> :kind Integer
Integer :: *
Prelude> :kind Maybe
Maybe :: * -> *
Prelude> :kind Either
Either :: * -> * -> *
Prelude> :kind (Either Integer)
(Either Integer) :: * -> *
Prelude> :kind (Either Integer String)
(Either Integer String) :: *
```

### Polymorphism

Polymorphism (from Greek πολύς, polys, “many, much” and μορφή, morphē, “form, shape”) is the provision of a single interface to entities of different types. A polymorphic type is one whose operations can also be applied to values of some other type, or types. Polymorphism is usually connected with object-oriented programming today, however, there are even more powerful types of polymorphism in functional programming languages, such as Haskell or Clojure.

We already used type classes and type variables - the basic enablers of polymorphism in Haskell. **Parametric polymorphism** refers to the situation when the type of a value contains one or more (unconstrained) type variables, so that the value may adopt any type that results from substituting those variables with concrete types. It is when the type variable *is not constrained* by some type class. For example, length of a list `[a]`

works for any type `a`

. In this tutorial, there was the `map`

function with type `(a -> b) -> [a] -> [b]`

- also a parametric polymorphism. This type of polymorphism doesn’t know anything about the type which it will be used with. The behaviour is abstracted regardless of a concrete type. This is a somewhat limiting but extremely useful property known as versatility.

**Ad-hoc polymorphism** refers to the situation when a value is able to adopt any one of a defined set of types because it, or a value it uses, has been given a separate definition for each of those types. This is a situation when the type variable *is constrained* by some type class. Thanks to that extra information about the given *still-generic* type, it is possible to use behaviour defined during class instantiation. Haskell even allows class instances to be defined for types which are themselves polymorphic - you can make your implementation of an arbitrary list an instance of some class. This polymorphism is not only about functions, but also about values - recall `Bounded`

class with `minBound`

and `maxBound`

values which are different for each instance.

There are some other types of polymorphism that are implemented in some extensions to Haskell, e.g. rank-N types and impredicative types. But there are also types of polymorphism that are not supported in Haskell, for example, subtyping and inclusion polymorphism.

### Own typeclass and instance

There are some commonly used typeclasses and their instances available and you can create your own, as well. You need to use keyword `class`

to defined functions for that typeclass and also optionally a class inheritance, i.e. a base class, which is extended. There can be even more, so the inheritance forms lattices.

Contrary to Java interfaces, apart from function declarations, Haskell typeclasses can also contain function implementations.

Next, you create typeclass instances using the keyword `instance`

, which means you define or (re-define) functions for that class.

```
-- from https://en.wikibooks.org/wiki/Haskell/Classes_and_types#A_concerted_example
-- Location, in two dimensions.
class Located a where
getLocation :: a -> (Int, Int)
class (Located a) => Movable a where
setLocation :: (Int, Int) -> a -> a
-- An example type, with accompanying instances.
data NamedPoint = NamedPoint
{ pointName :: String
, pointX :: Int
, pointY :: Int
} deriving (Show)
instance Located NamedPoint where
getLocation p = (pointX p, pointY p)
instance Movable NamedPoint where
setLocation (x, y) p = p { pointX = x, pointY = y }
-- Moves a value of a Movable type by the specified displacement.
-- This works for any movable, including NamedPoint.
move :: (Movable a) => (Int, Int) -> a -> a
move (dx, dy) p = setLocation (x + dx, y + dy) p
where
(x, y) = getLocation p
```

## Basic typeclasses in detail

### Deriving

We have already used the keyword `deriving`

many times. It is kind of magic which will automatically derive an instance of desired typeclass(es) so you don’t have to write functions on your own.

You can derive only built-in typeclasses:

`Eq`

= (in)equality based on arguments`Ord`

=`compare`

,`min`

,`max`

and comparison operators`Show`

= to`String`

conversion`Read`

= from`String`

conversion`Enum`

= enumerations only (no arguments), list`..`

syntax`Bounded`

= only for enumerations or just one arguments,`minBound`

and`maxBound`

You can use `deriving`

for your own classes, but you need to put some (advanced) effort in it by using Data.Derive and Template Haskell.

### Read and Show

If you derive default implementation of instances for `Show`

and `Read`

the string representing the data is actually the same as you would write it in Haskell code:

```
Prelude> data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Show, Read)
Prelude>
Prelude> myTree = Node (Leaf 8) (Node (Leaf 70) (Leaf 15))
Prelude> show myTree
"Node (Leaf 8) (Node (Leaf 70) (Leaf 15))"
Prelude> read "Node (Leaf 5) (Leaf 100)"
*** Exception: Prelude.read: no parse
Prelude> (read "Node (Leaf 5) (Leaf 100)") :: Tree Int
Node (Leaf 5) (Leaf 100)
```

```
class Show a where
showsPrec :: Int -> a -> ShowS
show :: a -> String
showList :: [a] -> ShowS
{-# MINIMAL showsPrec | show #-}
-- Defined in ‘GHC.Show’
```

When you make own `read`

and `show`

, you should ensure that after using `read`

on a string produced by `show`

, you will get the same data:

```
data Tree a = Leaf a | Node (Tree a) (Tree a)
size :: Num a => Tree b -> a
size (Leaf _) = 1
size (Node l r) = size l + size r
instance (Show a) => Show (Tree a) where
show (Leaf x) = show x
show (Node l r) = show l ++ " " ++ show r -- would be possible to write read for this?
```

`show`

is (quite often) abused to represent fancy string representations, but it is adviced to name such functions differently (such as `myShow`

), or to use a pretty-printing library such as Text.PrettyPrint, pretty, pretty-simple or prettyprinter.

Typeclass `Read`

is a bit more complex. If you want to make your own implementation, you need to write a parser. Parsing will be covered later on during the course. Basically, it tries to convert `String`

to `a`

and return it together with the remaining `String`

.

```
class Read a where
readsPrec :: Int -> ReadS a
readList :: ReadS [a]
GHC.Read.readPrec :: Text.ParserCombinators.ReadPrec.ReadPrec a
GHC.Read.readListPrec :: Text.ParserCombinators.ReadPrec.ReadPrec [a]
{-# MINIMAL readsPrec | readPrec #-}
-- Defined in `GHC.Read'
```

### Numerics

For numbers, there are several built-in typeclasses making numeric computing more flexible:

`Num`

`Real`

`Integral`

`RealFrac`

`Fractional`

`Floating`

`RealFloat`

(subclass of`Floating`

and`RealFrac`

)

If you don’t need to explicitly specify the type of number, use the typeclass constraint in the declaration of function type. This is a general rule of thumb: be as much generic, as possible.

### Comparison

There are two basic typeclasses - `Eq`

and its subclass `Ord`

that specify comparisons.

```
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
{-# MINIMAL (==) | (/=) #-}
-- Defined in ‘GHC.Classes’
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(<=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(>=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
{-# MINIMAL compare | (<=) #-}
-- Defined in ‘GHC.Classes’
```

You can again implement your own instances of those classes:

```
data Tree a = Leaf a | Node (Tree a) (Tree a)
size :: Num a => Tree b -> a
size (Leaf _) = 1
size (Node l r) = size l + size r
instance (Show a) => Show (Tree a) where
show (Leaf x) = show x
show (Node l r) = show l ++ " " ++ show r -- would be possible to write read for this?
instance Eq (Tree a) where
(==) t1 t2 = (size t1) == (size t2)
instance Ord (Tree a) where
compare t1 t2 = compare (size t1) (size t2)
```

### Enum and Bounded

Class `Enum`

defines operations on sequentially ordered types and it is a subclass of `Bounded`

which defines just `minBound`

and `maxBound`

values. As you can see below, `Enum`

describes 8 functions but only 2 are required (other will be derived based on that). Functions `toEnum`

and `fromEnum`

serve for specifying the order by numbering with `Int`

s.

```
class Enum a where
succ :: a -> a
pred :: a -> a
toEnum :: Int -> a
fromEnum :: a -> Int
enumFrom :: a -> [a]
enumFromThen :: a -> a -> [a]
enumFromTo :: a -> a -> [a]
enumFromThenTo :: a -> a -> a -> [a]
{-# MINIMAL toEnum, fromEnum #-}
```

When you derive `Enum`

, the order will be generated as left-to-right order of data constructors (without parameters, an enumeration consists of one or more nullary ones). Similarly, deriving `Bounded`

will use the first and the last data constructor.

Enumerations have also the `..`

syntactic sugar. For example, `[1..10]`

is translated to `enumFromThen 1 10`

and `[1,5..100]`

is translated to `enumFromThenTo`

## Mathematical Typeclasses

Now we are going to spend some time with predefined and important typeclasses that capture important concepts in Haskell that are widely used in many projects. Typeclass always says something about the structure of the type and what you can do with that. Also, there are some laws and it is very tightly related to math – specifically the algebra and the category theory.

After learning common typeclasses, it is not just easier to use them and understand a code written by other developers, but it also helps with designing own custom typeclasses. You can always find out more about a typeclass and instances with GHCi `:info`

command.

### Intro: Mathematical foundations

The relation between math and Haskell is very strong. You can observe it everywhere. Haskell functions are very similar to mathematical functions when you talk about their type, definitions with `let`

and `where`

keywords, guards with `otherwise`

, function compositions, and so on. In this tutorial, we are going to see this relation even more – with typeclasses that come from the mathematical world. You should be already familiar with basic abstract algebra (esp. algebraic structures with a single binary operation).

When getting into the math, you should know that Haskell is based not just on the basic algebra, set theory, and logic, but also on the category theory. In order to sometimes mention the relation, we will briefly explain what it is about. If you want to know more, please refer to some mathematical tutorials on your own.

#### Category theory

Category theory is a higher abstraction level over *Monoid*, *Semigroup*, and similar algebraic structures. Actually, it is so abstract that it can describe so many things … that it is very hard to comprehend. The “best practice” among programmers is to learn it bit by bit and return to it from time to time until things “click” together. This “click” means putting together the theory and its practical applications.

A **category** is a structure or collection *C* with three components:

- a collection of
**objects**,*ob(C)*, - a collection of
**morphisms**,*hom(C)*, that ties two objects together; sometimes they are called**arrows**, - a
**composition**of morphisms (similar to function composition).

There are many categories, for example, **Set** category has all possible sets as objects, standard functions as morphisms, and classical function composition. There are also three laws:

- the composition of category must be associative (i.e.,
*f ∘ (g ∘ h) = (f ∘ g) ∘ h*), - the category needs to be closed under the composition operation (i.e., for all applies
*h = f ∘ g ⇒ h ∈ C*), - for every object
*A ∈ ob(C)*there is an identity function*idA: A → A*,*idA ∈ hom(C)*.

#### The Hask category

In Haskell, we have the **Hask** category where:

*ob(Hask)*are**types**(`Char`

,`Int`

,`Double`

,`[Integer]`

,`Person`

,`Int -> String`

, etc.),*hom(C)*are**functions**(`show`

,`id`

,`length`

,`words`

,`flip`

,`reverse`

, etc.),- composition is
**function composition**`(.)`

.

The identity function is for every *o ∈ ob(Hask)* the polymorphic `id`

function. The associativity of the composition is assured and in *hom(C)* there are all the functions, even those created by composition. That’s it for now – now we will show some typeclasses, their laws and come back to **Hask** when necessary…

### Semigroup, Monoid, …

`Monoid`

is the most simple typeclass we will learn. You can recall the monoid from the algebra – it is an algebraic structure with one binary operation that is associative and there is also one identity element. The same goes for Haskell – the operation is called `mappend`

and the identity is `mempty`

(the first letter `m`

if for **m**onoid).

Since `base-4.11.0.0`

, the `Monoid`

is a subclass of `Semigroup`

(just like in algebra). `Semigroup`

defines just binary operation which is associative. In Haskell, the binary operation is `(<>)`

(infixr 6)

```
class Semigroup s where
(<>) :: s -> s -> s -- binary associative operation
class Semigroup m => Monoid m where
mempty :: m -- identity of mappend
mappend :: m -> m -> m
mappend = (<>) -- binary operation from Semigroup
mconcat :: [m] -> m
mconcat = foldr mappend mempty -- fold with mappend (catamorphism)
```

The law of monoid says that `mappend`

must be associative and `mempty`

is a real identity when working with `mappend`

:

```
mappend x (mappend y z) == mappend (mappend x y) z
-- the same in infix:
x `mappend` (y `mappend` z) == (x `mappend` y) `mappend` z
mappend x mempty == x
mappend mempty x == x
```

If you take a look at the documentation of Data.Monoid, you might notice few more things:

- by default, a synonym for
`mappend`

is`(<>)`

so you can simply use it as operator`x <> b`

(notice that it is not the same as not-equals in other languages), - multiple newtypes for specifying monoid for basic types, like
`Sum`

and`Product`

for numeric types,`All`

and`Any`

for booleans,`First`

and`Last`

for maybes and few more.

```
Prelude> import Data.Monoid
Prelude Data.Monoid> :info Sum
newtype Sum a = Sum {getSum :: a} -- Defined in ‘Data.Monoid’
...
Prelude Data.Monoid> :info Product
newtype Product a = Product {getProduct :: a}
...
Prelude Data.Monoid> (Product 5) <> (Product 2)
Product {getProduct = 10}
Prelude Data.Monoid> mempty :: Product Int
Product {getProduct = 1}
Prelude Data.Monoid> (Sum 5) <> (Sum 2)
Sum {getSum = 7}
Prelude Data.Monoid> mempty :: Sum Int
Sum {getSum = 0}
Prelude Data.Monoid> mconcat (map Sum [1..5])
Sum {getSum = 15}
Prelude Data.Monoid> mconcat (map Product [1..5])
Product {getProduct = 120}
```

#### Example: textual types

One of the very practical usages of `mappend`

is string concatenation, which is independent of its concrete implementation:

```
{-# LANGUAGE OverloadedStrings #-}
import Data.Text (Text)
s1 :: String
s1 = "hello"
s2 :: String
s2 = "monoid"
t1 :: Text
t1 = "hello"
t2 :: Text
t2 = "monoid"
s1 <> ", " <> s2 -- instead of s1 ++ ", " ++ s2
t1 <> ", " <> t2 -- works the same for text!
```

Here, obviously `mappend`

is string concatenation and `mempty = ""`

.

#### Example: Maybe

From `:info Monoid`

, we can see that `Maybe a`

is an instance of `Monoid`

iff (=if and only if) `a`

is an instance of `Monoid`

. Then, the `(<>)`

is “propagated” inside and obviously the identity is `Nothing`

.

```
Prelude Data.Maybe Data.Semigroup> (Just "a") <> (Just "b")
Just "ab"
Prelude Data.Maybe Data.Semigroup> (Just "a") <> Nothing
Just "a"
Prelude Data.Maybe Data.Semigroup> (Just "a") <> Nothing <> (Just "b")
Just "ab"
Prelude Data.Maybe Data.Semigroup> Nothing <> Nothing
Nothing
Prelude Data.Maybe Data.Semigroup> mconcat [Just "a", Nothing, Just "b"]
Just "ab"
Prelude Data.Maybe Data.Semigroup> mempty :: Maybe String
Nothing
```

#### Verify the laws

As said, there are some laws (identity and associativity in this case) that should be valid, but the compiler cannot enforce it. Whenever you introduce your own instance of `Monoid`

or other structure with some laws that are expected to be valid, use tests to prove it. One way is to write the properties on your own. The second and better one is to use checkers, where many standard properties are prepared for you…

#### Others from basic algebra

Apart from basic `Monoid`

from algebra, there are also other variants. You might find interesting to learn more about:

- semigroupoids (Semigroupoid, Grupoid),
- groups (Group, Abelian),
- etc.

It is possible to write own instances of `Monoid`

or other typeclasses. However, mind that compiler *won’t* check if laws are valid in your instance. For such checks, you can use testing frameworks (esp. property testing), which will be covered later on.

### Functor

A functor is a way to apply a function to values inside some structure, while the structure remains intact. For example, if you want to change values in a list, tree or in Either without dealing with complexity and internal structure.

```
class Functor f where -- f is type constructor of kind * -> *
fmap :: (a -> b) -> f a -> f b
```

The definition says that there is a function `fmap`

which applies a function of type `a -> b`

on elements in functor `f`

with inner type `a`

and the result will be functor `f`

with inner type `b`

. Moreover, there are two laws:

```
-- identity (fmap doesn't do anything more than applying given function)
fmap id == id
-- composition
fmap (f . g) == fmap f . fmap g
```

Let’s try it with basic containers like list, `Maybe`

, and `Either`

:

```
Prelude> fmap (*2) [1..5] -- just like map!
[2,4,6,8,10]
Prelude> fmap (show . (*2)) [1..5] -- just like map!
["2","4","6","8","10"]
Prelude> fmap (*2) (Just 7)
Just 14
Prelude> fmap (*2) Nothing
Nothing
Prelude> fmap (+10) (Left 5)
Left 5 -- no change!
Prelude> fmap (+10) (Right 5)
Right 10 -- changed, because "Either c" is functor for whatever "c" - it doesn't care
```

Just as with Monoid, you can take a look at the documentation of Data.Functor. Again, there is an operator alias, in this case `(<$>)`

for `fmap`

(denoting a sort of “wrapped” or “inside” apply). There are two more – `<$`

and `$>`

(just flipped `<$`

). Flipped version of `(<$>)`

is `(<&>)`

.

```
Prelude Data.Functor> (*2) <$> [1..5]
[2,4,6,8,10]
Prelude Data.Functor> [1..5] <&> (*2)
[2,4,6,8,10]
Prelude Data.Functor> 2 <$ [1..5]
[2,2,2,2,2]
Prelude Data.Functor> [1..5] $> 2
[2,2,2,2,2]
Prelude> (*2) <$> (Just 7)
Just 14
Prelude> 2 <$ (Just 7)
Just 2
Prelude> (Just 7) $> 2
Just 2
```

These examples might seem a bit too simple, but you can have any instance of `Functor`

without knowing the structure and implementation of it and affect what is inside by these two (four if counting also flipped) simple operators.

#### Lifting

Lifting is a concept that allows you to transform a function into a corresponding function within another (usually a more general) setting. Lifting is again a concept taken from mathematics and category theory (see wikipedia.

```
data Point2D a = Point2D a a
deriving Show
instance Functor Point2D where
fmap f (Point2D x y) = Point2D (f x) (f y)
liftF0 :: a -> Point2D a
liftF0 x = Point2D x x
liftF1 :: (a -> b) -> Point2D a -> Point2D b
liftF1 = fmap
liftF2 :: (a -> b -> c) -> Point2D a -> Point2D b -> Point2D c
liftF2 f (Point2D x1 x2) (Point2D y1 y2) = Point2D (f x1 y1) (f x2 y2)
origin :: Point2D Int
origin = liftF0 0
doublePoint :: Point2D Int -> Point2D Int
doublePoint = liftF1 (*2)
plusPoints :: Point2D Int -> Point2D Int -> Point2D Int
plusPoints = liftF2 (+)
```

#### Functors on Hask category

In mathematics, a functor is a type of mapping between categories arising in category theory. Functors can be thought of as homomorphisms between categories. In the category of small categories, functors can be thought of more generally as morphisms. (wikipedia)

We have some categories which have objects and morphisms that relate our objects together. Functor *F: C → D* relates categories *C* and *D* together - it is a transformation between categories:

- maps every object
*A*from category*C*to object*F(A)*in category*D* - maps every morphism
*f: A → B*from category*C*to morphism*F(f): F(A) → F(B)*in category*D*

```
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
-- fmap :: (a -> b) -> (f a -> f b)
```

There is also the identity law for functions and they must be homomorphic that, of course, apply for functors in Haskell:

```
fmap id == id
fmap (f . g) = fmap f . fmap g
```

### Applicative

Another important typeclass is Control.Applicate. Notice that it is not “Data” anymore, but “Control” instead! It is an intermediate structure between a `Functor`

and a `Monad`

. It is simpler than `Monad`

, not so powerful, but sufficient in many use cases, and also easier to understand - it is **Applicative functor**.

In functor, we applied a function over a “wrapped” value to get a resulting “wrapped” value. In applicative, we have the function wrapped, as well:

```
class Functor f => Applicative f where
pure :: a -> f a -- lift a
(<*>) :: f (a -> b) -> f a -> f b -- sequential application
--(<$>) :: (a -> b) -> f a -> f b -- this is from functor
```

Function `pure`

only lifts something into applicative structure `f`

. The more interesting part is the “tie-fighter” operator `<*>`

that applies a lifted function over an applicative. You can find out in the documentation following similar functions and partial functions as in Data.Functor:

```
(<*) :: f a -> f b -> f a
(*>) :: f a -> f b -> f b
liftA :: (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA3 :: (a -> b -> c -> d) -> f a -> f b -> f c -> f d
```

There are again some laws:

```
-- identity
pure id <*> v == v
-- composition
pure (.) <*> u <*> v <*> w == u <*> (v <*> w)
-- homomorphism
pure f <*> pure x = pure (f x)
-- interchange
u <*> pure y = pure ($ y) <*> u
```

```
Prelude> linfunc x = 2 * x + 10
Prelude> (Just lin
lines linfunc
Prelude> (Just linfunc) <*> (Just 5)
Just 20
Prelude> pure linfunc <*> (Just 5)
Just 20
Prelude> pure linfunc <*> Nothing
Nothing
Prelude> Nothing <*> (Just 5)
Nothing
Prelude> (Just 5) <* (Just 10)
Just 5
Prelude> (Just 5) *> (Just 10)
Just 10
Prelude> pure linfunc <*> (Left 7)
Left 7
Prelude> pure linfunc <*> (Right 15)
Right 40
Prelude> (Right 5) *> (Left 10)
Left 10
Prelude> (Right 5) <* (Left 10)
Left 10
Prelude Control.Applicative> (Right 15) <**> pure linfunc
Right 40
-- Lifts are already prepared in Control.Applicative
Prelude Control.Applicative> liftA2 (+) (Just 5) (Just 10)
Just 15
Prelude Control.Applicative> liftA2 (+) (Just 5) Nothing
Nothing
Prelude Control.Applicative> liftA2 (+) (Left "error") (Right 7)
Left "error"
Prelude Control.Applicative> liftA2 (+) (Right 15) (Right 7)
Right 22
```

#### Actions vs. functions

In Haskell terminology, we call `Functor f => f a`

an **action**. Actions have the power to do some side effect but not necessarily (e.g., `Just "no effect"`

). For example, `liftA2`

is described as a function that lifts a binary function to actions. Special sort of actions are I/O actions that do something with input and output, but there can be also other actions making side effects.

### Monad

The most famous (and scary :-)) typeclass for Haskell students is Control.Monad. It defines basic operations over a monad, a term from category theory. From the perspective of a Haskell programmer, however, it is best to think of a monad as an “abstract datatype of actions”. Haskell’s `do`

expressions provide a convenient syntax for writing monadic expressions. This time we will start Monads (operations, laws, basic behavior, etc.) and next time we will get deeper with some more practical use-cases.

```
class Applicative m => Monad m where
(>>=) :: m a -> (a -> m b) -> m b -- compose two actions, passing the result
(>>) :: m a -> m b -> m b -- compose two actions, discarding the result
return :: a -> m a -- inject a value into the monadic type.
-- (<**>):: f a -> f (a -> b) -> f b -- from Controll.Applicative
-- (*>) :: f a -> f b -> f b -- from Controll.Applicative
-- pure :: a -> f a -- from Controll.Applicative
```

Function `return`

works just as `pure`

in `Applicative`

. Why having two same functions? Historically; PureScript, for instance, has just `pure`

both for the Applicative and Monad.

`>>=`

is bind, which takes a monadic value (again, this is some “wrapped value”) and a function, which takes an unwrapped value and transforms it into a monadic value.

`>>`

is a sequencing operator, which “passes” computation from monad to another.

Again, there are functions `liftM`

and laws:

```
-- identity
return a >>= k == k a
m >>= return == m
-- associativity
(m >>= f) >>= g = m >>= (\x -> f x >>= g)
```

```
Prelude Control.Monad> (Just 5) >> (Just 10)
Just 10
Prelude Control.Monad> (Just 5) >>= \x -> (Just (x+10))
Just 15
Prelude Control.Monad> return 5 >>= \x -> (Just (x+10))
Just 15
Prelude Control.Monad> (Left "err") >>= (\x -> return (x+10))
Left "err"
```

#### Do syntax

Monads in Haskell are so useful that they got their own special syntax called `do`

notation. We first introduced it way back in the “Simple input and output” chapter. There, we used it to sequence input/output operations, but we hadn’t introduced monads yet. Now, we can see that IO is yet another monad.

Imagine we have a sequence operation like this:

```
Prelude> Just 7 >>= (\x -> Just (show x ++ "!"))
Just "7!"
Prelude> Just 7 >>= (\x -> Just "!" >>= (\y -> Just (show x ++ y)))
Just "7!"
Prelude> print 3 >> print 5 >> print 7
3
5
7
```

Haskell provides the `do`

notation so we can avoid writing all the lambdas:

```
foo :: Maybe String
foo = do
x <- Just 7
y <- Just "!"
Just (show x ++ y)
```

or

```
main = do
print 3
print 5
print 7
```

In `do`

, you can use basic sequencing `>>`

, `>>=`

operator by binding `<-`

and `let`

instead of `let-in`

:

```
main = do
putStrLn "Enter name:"
name <- getLine -- getLine >>= (\name -> ...)
putStrLn ("Hello, " ++ name ++ "!")
let answer = 42 -- let answer = 42 in (...)
putStrLn "The answer to life, the universe and everything is..."
print answer -- let and binding cannot be the last in do!
```

#### Loops

You might hear that “do” provides an imperative-like way of programming… That’s true but it is really just *imperative-like* from a visual point of view, it is still purely functional! But even in math and functions, you can introduce something like `for`

or `while`

loops. When you want to compute some result like factorial, sum, length of a list it is natural to use recursion. With actions, it might give more sense to use loops (even when they are actually done by recursion):

```
import System.Random
import Control.Monad.Loops
promptAnswer :: IO Int
promptAnswer = do
putStrLn "Guess the answer: "
x <- getLine
return (read x)
guessAnswer :: Int -> IO Bool
guessAnswer x = do
guess <- promptAnswer
return (guess /= x)
main = do
putStrLn "Welcome to GUESS 1 to 10 game"
answer <- randomRIO (1, 10)
whileM_ (guessAnswer answer) $ do -- whileM_ :: Monad m => m Bool -> m a -> m ()
putStrLn "Incorrect!"
putStrLn "Good job!"
```

For other loops, visit Control.Monad.Loops and this article.

#### Monads in category theory

Again, monad comes from math and more specifically from category theory. A monad is a special type of functor, from a category to that same category (i.e., it is *endofunctor*), that supports some additional structure. Monad is a functor *M: C → C* with two morphisms for every object *X* from *C*:

*unit: X → M(X)*~`return :: Monad m => a -> m a`

*join: M(M(X)) → M(X)*~`(>>=) :: Monad m => m a -> (a -> m b) -> m b`

## Further reading

- Haskell: Polymorphism
- Typeclassopedia
- Haskell: OOP vs type classes
- WikiBooks Haskell: Classes and types
- Functors, Applicatives, And Monads In Pictures
- Haskell and Category Theory
- Category Theory for Programmers by Bartosz Milewski
- LYAH: Functors, Applicative Functors and Monoids
- LYAH: A Fistful of Monads
- Haskell: Monad