## Introduction

### Expressions

- Expressions include concrete values, variables, and also functions
- Functions are expressions that are applied to an argument, and hence
can be
*reduced*or*evaluated*

### Infix/Prefix

```
div (prefix) -> `div` (infix)
+ (infix) -> (+) (prefix)
```

### Let vs Where

Let introduces an expression, so it can be used wherever you can have an expression, but where is a declaration and is bound to a surrounding syntactic construct.

### Typeclasses

Typeclasses are a way of adding additional functionality that is
reusable across all the types that have instances of that typeclass.
`Num`

is a typeclass for most numeric types, that provide the basic
operators `(+)`

, `(-)`

, `(*)`

, `(/)`

etc.

### Datatype declaration

A datatype declaration defines a type constructor and data constructors. Data constructors are the values of a particular type, and are also functions that let us create data, or values, of a particular type.

### Sectioning

Refers to the partial application of infix operators.

```
let x = 5
let y = (2^)
let z = (^2)
y x -- 32
z x -- 25
let celebrate = (++ " woot!")
celebrate "naptime" -- "naptime woot!"
celebrate "dogs" -- "dogs woot!"
```

### Types

#### Polymorphism

- Parametric polymorphism
- Refers to type variables, or parameters, that are fully polymorphic
- When unconstrained by a typeclass, the final concrete type could be anything

- Constrained polymorphism
- Puts typeclass constraints on the variable, decreasing the number of concrete types it could be, but increasing what you can actually do with it by defining and bringing into scope a set of operations

Numeric literals are polymorphic and stay so until given a more specific type.

#### Parametricity

*parametricity* means that the behaviour of a function with respect to
the types its (parametric polymorphic) arguments is uniform. The
behaviour cannot change just because it was applied to an argument of
a different type.

#### Making things more polymorphic

```
-- fromIntegral :: (Num b, Integral a) => a -> b
-- e.g.
6 / fromIntegral (length [1,2,3])
```

## Laziness and Performance

Laziness can be a useful tool for improving performance, but more often than not it reduces performance by adding a constant overhead to everything. Because of laziness, the compiler can’t evaluate a function argument and pass the value to the function, it has to record the expression in the heap in a suspension (or thunk) in case it is evaluated later. Storing and evaluating suspensions is costly, and unnecessary if the expression was going to be evaluated anyway.

One can force eager evaluation by prepending a bang(`!`

) in front of
the expression.

## Type classes

Where a declaration of a type defines how that particular type is created, a declaration of a typeclass defines how a set of types are consumed or used in computations.

As long as a type implements, or instantiates a typeclass, then standard functions implemented on the typeclass can be used.

```
data DayOfWeek =
Mon | Tue | Wed | Thu | Fri | Sat | Sun
-- day of week and numerical day of month
data Date =
Date DayOfWeek Int
```

Because Eq is not derived in the typeclass, we need to instantiate one of our own:

```
instance Eq DayOfWeek where
(==) Mon Mon = True
(==) Tue Tue = True
(==) Wed Wed = True
(==) Thu Thu = True
(==) Fri Fri = True
(==) Sat Sat = True
(==) Sun Sun = True
(==) _ _ = False
instance Eq Date where
(==) (Date weekday dayOfMonth) (Date weekday' dayOfMonth') =
weekday == weekday' && dayOfMonth = dayOfMonth'
```

Typeclass instances are unique parings of the typeclass and a type. They define the ways to implement the typeclass methods for that type.

### IO

An IO action is an action that, when performed, has side effects, including reading from input and printing to the screen, and will contain a return value.

In `IO ()`

, `()`

denotes an empty tuple, referred to as a *unit*. A
unit is both a value and a type, that has only one inhabitant.

### Summary

- A typeclass defines a set of functions and/or values;
- Types have instances of that typeclass
- The instances specify the ways that type uses the functions of the typeclass

## Lists

```
data [] a = [] | a : [a]
```

### Extracting portions of lists

```
take :: Int -> [a] -> [a]
drop :: Int -> [a] -> [a]
splitAt :: Int -> [a] -> ([a], [a])
```

```
takeWhile :: (a -> Bool) -> [a] -> [a]
dropWhile :: (a -> Bool) -> [a] -> [a]
```

### Transforming lists of values

```
map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
```

```
map (+1) [1,2,3,4] -- [2,3,4,5]
map (1-) [1,2,3,4] -- [0,-1,-2,-3]
```

```
filter :: (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter pred (x:xs)
| pred x = x : filter pred xs
| otherwise = filter pred xs
```

```
zip :: [a] -> [b] -> [(a,b)]
zip [1,2] [3,4] -- [(1,3), (2,4)]
zipWith (+) [1,2,3] [10,11,12] -- [11,13,15]
```

### Folding lists

Folds as a general concept are called *catamorphisms*.
*Catamorphisms* are a means of deconstructing data. If the spine of
the list is the structure of a list, then a fold is what can reduce
that structure.

```
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z xs =
case xs of
[] -> z
(x:xs) -> f x (foldr f z xs)
```

## Algebraic Datatypes

A type can be thought of as an enumeration of constructors that have zero or more arguments.

Haskell offers sum types, product types, product types with record syntax, type aliases, and a special datatype called a newtype that offers a different set of options and constraints from either type synonyms or data declarations.

```
data Bool = False | True
-- [1] [2] [3] [4] [5] [6]
data [] a = [] | a : [a]
-- [7] [8] [9]
```

- Keyword
*data*to signal that what follows is a data declaration, or a declaration of a datatype - Type constructor (with no arguments)
- Equals sign divides the type constructor from the data constructor
- Data constructor. In this case, a data constructor that takes no
arguments, so is called a
*nullary*constructor. - Pipe denotes a sum type, which indicates a logical disjunction
(colloquially
*or*) in what values can have that type - Constructor for the value True, another nullary constructor
- Type constructor with an argument. The argument is a polymorphic type variable, so the list’s argument can be of different types
- Data constructor for the empty list
- Data constructor that takes two arguments, an a and also a [a]

### Data and type constructors

Type constructors are used only at the type level, in type signatures and typeclass declarations and instances. Types are static and resolve at compile time.

Data constructors construct the values at term level, values you can interact with at runtime.

Type and data constructors that take no arguments are constants. They can only store a fixed type and amount of data.

### Type constructors and kinds

Kinds are types of types, or types one level up. We represent kinds in
Haskell with `*`

. We know something is a fully applied, concrete type
when it is represented as `*`

. When it is `* -> *`

, it is still
waiting to be applied.

```
-- :k Bool
Bool :: *
-- :k [Int]
[Int] :: *
-- :k []
[] :: * -> *
```

Both `Bool`

and [Int] are fully applied, concrete types, so their kind
signatures have no function arrows.

### Types vs Data

When data constructors take arguments, those arguments refer to other types.

```
data Price =
-- (a)
Price Integer deriving (Eq, Show)
-- (b) [1]
-- type constructor a
-- data constructor b
-- type argument [1]
```

### What makes these datatypes algebraic?

Algebraic datatypes are so, because we can describe the patterns of argument structures using two basic operations: sum and product.

The cardinality of a datatype is the number of possible values it defines. Knowing how many possible values inhabit a type can help reason about programs.

The cardinality of `Bool`

is 2, only being to take on `True`

or `False`

.

Datatypes that only contains a unary constructor always have the same cardinality as the type they contain.

```
data Goats = Goats Int deriving (Eq, Show)
```

Here, `Goats`

has the cardinality of `Int`

.

### Sum Types

Cardinality is obtained through summation. Example, Bool:

```
data Bool = True | False
```

In this case, the cardinality of `Bool`

is the sum of the cardinality
of `True`

and `False`

.

### Record syntax

```
data Person =
Person { name :: String
, age :: Int }
deriving (Eq, Show)
```

## Signaling Adversity

### Maybe

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

```
type Name = String
type Age = Integer
data Person = Person Name Age Deriving (Eq, Show)
mkPerson :: Name -> Age -> Maybe Person
mkPerson name age
| name /= "" && age >=0 = Just $ Person name age
| otherwise = Nothing
```

mkPerson is a *smart constructor*. It allows us to construct values
only if it meets a certain criteria.

### Either

We use an `either`

to figure out which criteria is not met:

```
data Either a b = Left a | Right b
```

```
data Person Invalid = NameEmpty | AgeTooLow deriving (Eq, Show)
mkPerson :: Name -> Age -> Either PersonInvalid Person
mkPerson name age
| name /= "" && age >=0 - Right $ Person name age
| name == "" = Left PersonInvalid
| otherwise = Left AgeTooLow
```

`Left`

is used as the invalid or error constructor. `Functor`

will not
map over the left type argument because it has been applied away.

#### Signalling Multiple errors

```
type Name = String
type Age = Integer
type ValidatePerson a = Either [PersonInvalid] a
data Person = Person Name Age deriving Show
data PersonInvalid = NameEmpty | AgeTooLow deriving (Eq, Show)
ageOkay :: Age -> Either [PersonInvalid] Age
ageOkay age = case age >= 0 of
True -> Right age
False -> Left [AgeTooLow]
nameOkay :: Name -> Either [PersonInvalid] Name
nameOkay name = case name == "" of
True -> Left [NameEmpty]
False -> Right name
mkPerson :: Name -> Age -> ValidatePerson Person
mkPerson name age =
mkPerson' (nameOkay name) (ageOkay age)
mkPerson' :: ValidatePerson Name
-> ValidatePerson Age
-> ValidatePerson Person
mkPerson' (Right nameOk) (Right ageOk) = Right (Person nameOk ageOk)
mkPerson' (Left badName) (Left badAge) = Left (badName ++ badAge)
mkPerson' (Left badName) _ = Left badName
mkPerson' _ (Left badAge) = Left badAge
```

### Anamorphisms

*Anamorphisms* are the dual of *catamorphisms*. Catamorphisms, or
folds, break data structures down, anamorphisms builds up data
structures.

```
-- iterate is like a very limited unfold that never ends
iterate :: (a -> a) -> a -> [a]
take 10 $ iterate (+1) 0
[0,1,2,3,4,5,6,7,8,9]
--unfoldr is more general
unfoldr :: (b -> Maybe (a,b)) -> b -> [a]
take 10 $ unfoldr (\b -> Just (b, b+1)) 0
[0,1,2,3,4,5,6,7,8,9]
```

## Monoids

In Haskell, algebras are implemented with typeclasses; the typeclasses
define the set of operations. When we talk about operations over a
set, the set is the *type* the operations are for.

One of those algebras we use in Haskell is Monoid.

`A monoid is a binary associative pattern with an identity.`

A monoid is a function that takes two arguments and follows two laws: associativity and identity.

- Associativity: arguments can be regrouped or paranthesised in different orders and give the same result
- Identity: there exists some value such that when it is passed as input to the function, the operation is rendered moot and the other value is returned. E.g. adding 0, multiplying by 1

Monoids are the pattern of summation, multiplication and list concatenation, among other things.

```
class Monoid m where
mempty :: m
mappend :: m -> m -> m
mconcat :: [m] -> m
mconcat = foldr mappend mempty
```

`mappend`

is how any two values that inhabit the type can be joined
together. `mempty`

is the identity value for that mappend operation.

### Examples of Monoids

#### List

```
mappend [1,2,3] [4,5,6]
-- [1,2,3,4,5,6]
mconcat [[1..3], [4..6]]
-- [1,2,3,4,5,6]
mappend "Trout" " goes well with garlic"
-- "Trout goes well with garlic"
instance Monoid [a] where
mempty = []
mappend = (++)
```

#### Integers

Integers form a monoid under summation and multiplication. Because it
is unclear which rule is to be followed, there is no Monoid class
under Integer, but there is the `Sum`

and `Product`

types that signal
which Monoid instance is wanted.

### Newtype

Using `newtype`

constrains the datatype to having a single unary data
constructor, and `newtype`

guarantees no additional runtime overhead
in “wrapping” the original type. The runtime representation of newtype
and what it wraps are always identical.

```
(<>) :: Monoid m => m -> m -> m
```

`<>`

is the infix version of `mappend`

.

Monoid instances must abide by the following laws:

```
-- left identity
mappend mempty x = x
-- right identity
mappend x mempty = x
-- associativity
mappend x (mappend y z) = mappend (mappend x y) z
mconcat = foldr mappend mempty
```

### Monoid instances in `Bool`

```
All True <> All True
-- All {getAll = True}
All True <> All False
-- All {getAll = False}
Any True <> Any False
-- Any {getAny = True}
Any False <> Any False
-- Any {getAny = False}
```

`All`

represents boolean *conjuction*, while `Any`

represents boolean disjunction.

For `Maybe`

, `First`

returns the “first” or leftmost non-Nothing
value. `Last`

returns the “last” or rightmost non-Nothing value.

```
(First (Just 1)) <> (First (Just 2))
-- First {getFirst = Just 1}
```

```
instance Monoid b => Monoid (a -> b)
instance (Monoid a, Monoid b) => Monoid (a,b)
instance (Monoid a, Monoid, b, Monoid c) => Monoid (a,b,c)
```

## Semigroups

Semigroups are like monoids, but without the identity constraint. The core operation remains binary and associative.

```
class Semigroup a where
(<>) :: a -> a -> a
(a <> b) <> c = a <> (b <> c)
```

```
data NonEmpty a = a :| [a] deriving (Eq, Ord, Show)
```

## Functors

A functor is a way to apply a function over or around some structure that we don’t want to alter. That is, we want to apply the function to the value that is “inside” some structure, and leave the structure alone.

Intuitively, a `Functor`

represents a “container” of some sort, along
with the ability to apply a function uniformly to every element in the
container. Another intuition of a Functor is that it represents some
sort of “computational context”.

This is why functors are generally introduced by way of fmapping over lists. No elements are removed or added, only transformed.

The typeclass `Functor`

generalises this pattern, so that this basic
idea can be used across different structures.

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

The argument `f a`

is a Functor `f`

that takes a type argument `a`

.
That is, the `f`

is a type that has an instance of the Functor
typeclass.

The return value is `f b`

. It is the same `f`

from `f a`

, while the
type argument b *possibly but not necessarily* refers to a different type.

*fmap* specialises to different types as such:

```
fmap :: (a -> b) -> f a -> f b
fmap :: (a -> b) -> [] a -> [] b
fmap :: (a -> b) -> Maybe a -> Maybe b
fmap :: (a -> b) -> Just a -> Just b
fmap :: (a -> b) -> Either a -> Either b
fmap :: (a -> b) -> (e,) a -> (e,) b
fmap :: (a -> b) -> Identity a -> Identity b
```

### Functor Laws

#### Identity

```
fmap id == id
```

If we fmap the identity function, it should have the same result as passing our value to identity.

#### Composition

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

#### Structure Preservation

```
fmap :: Functor f => (a -> b) -> f a -> f b
```

The *f* is constrained by the typeclass Functor, but that is all we
know about its type from this definition. Because the *f* persists
through the type of `fmap`

, whatever the type is, we know it must be a
type that can take an argument, as in `f a`

and `f b`

and that it will
be the “structure” we’re lifting the function over when we apply it to
the value inside.

### Examples

```
data WhoCares a =
ItDoesnt
| Matter a
| WhatThisIsCalled
deriving (Eq, Show)
```

In the above datatype, only `Matter`

can be *fmapped* over, because
the others are nullary, and there is no value to work with inside the
structure.

Here is a law-abiding instance of Functor.

```
instance Functor WhoCares where
fmap _ ItDoesnt = ItDoesnt
fmap _ WhatThisIsCalled = WhatThisIsCalled
fmap f (Matter a) = Matter (f a)
```

This is a law-breaking instance:

```
instance Functor WhoCares where
fmap _ ItDoesnt = WhatThisIsCalled
fmap f WhatThisIsCalled = ItDoesnt
fmap f (Matter a) = Matter (f a)
```

In this instance, the structure – not the values wrapped or contained within the structure – change.

### Maybe and Either Functors

```
data Two a b = Two a b
```

Notice `Two`

has the kind `* -> * -> *`

, however, functors are of kind
`* -> *`

, and hence functors on the type Two would be invalid. we can
reduce the kindness by doing the following:

```
instance Functor (Two a) where
fmap f (Two a b) = Two a (f b)
```

Notice that we didn’t apply `f`

to `a`

, because `a`

is now part of the
Functor structure, and is untouchable.

### Ignoring possibilities

The Functor instances for the Maybe and Either datatypes are useful if you tend to ignore the left cases, which are typically the error or failure cases. Because fmap doesn’t touch those cases, you can map your function right to the values that you intend to work with and ignore failure cases.

#### Maybe

```
incIfJust :: Num a => Maybe a -> Maybe a
incIfJust (Just n) = Just $ n + 1
incIfJust Nothing = Nothing
incMaybe :: Num a => Maybe a -> Maybe a
incMaybe = fmap (+1)
```

#### Either

```
incIfRight :: Num a => Either e a => Either e a
incIfRight (Right n) = Right $ n + 1
incIfRight (Left e) = Left e
-- can be simplified to
incEither :: Num a => Either e a => Either e a
incEither = fmap (+1)
```

### Summary

`Functor`

is a mapping between categories. In Haskell, this manifests
as a typeclass which lifts a function between to types over two new
types. This conventionally implies some notion of a function which can
be applied to a value with more structure than the unlifted function
was originally designed for. The additional structure is represented
by the use of a higher kinded type *f*, introduced by the definition
of the Functor typeclass.

To *lift over*, and later in Monad, to *bind over*, is a metaphor. One
way to think about it is that we can lift a function into a context.
Another is that we lift a function over some layer of structure to
apply it.

```
fmap (+1) $ Just 1 -- Just 2
fmap (+1) [1,2,3] -- [2,3,4]
```

In both cases, the function we’re lifting is the same. In the first case, we lift that function into a Maybe context in order to apply it, in the second case, into a list context.

The context determines how the function will get applied: the context is the datatype, the definition of the datatype, and the Functor instance we have for that datatype.

## Applicative

Monoid gives us a means of hashing two values of the same type together.

Functor is for function application over some structure we don’t want to have to think about.

The Applicative typeclass is a Monoidal Functor. The Applicative typeclass allows for function application lifted over structure (like Functor). But with Applicative the function we’re applying is also embedded in some structure. Because the function and the value it’s being applied to both have structure, we have to smash those structures together.

```
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
```

The `pure`

function embeds something into functorial (applicative)
structure.

`<*>`

is an infix operation called ‘apply’. This is very similar to
the types of fmap.

```
-- fmap
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
```

the Control.Applicative library provides some convenience functions:
`liftA`

, `liftA2`

and `liftA3`

:

```
liftA :: Applicative f => (a -> b) -> f a -> f b
liftA2 :: Appplicative f => (a -> b -> c) -> f a -> f b -> f c
liftA2 :: Appplicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
```

`liftA`

is just `fmap`

with an Applicative typeclass constraint as
opposed to a Functor typeclass constraint.

In `pure`

, the left type is handled differently from the right:

```
pure 1 :: ([a], Int) -- ([], 1)
pure 1 :: Either a Int -- Right 1
```

The left type is part of the structure, and the structure is not transformed by the function application.

In a sense, Applicative is Monoid bolted onto a Functor to be able to deal with functions embedded in additional structure. In another, we’re enriching function application with the very structure we were previously merely mapping over with Functor.

```
[(*2), (*3)] <*> [4,5] -- [2*4, 2*5, 3*4, 3*5]
= [8,10,12,15]
```

`<*>`

takes a functor that has a function in it, and another functor
and applies the function inside the functor. `<*>`

is left associative.

```
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
```

```
instance Applicative [] where
pure x = [x]
fs <*> xs = [f x | f <- fs, x <- xs]
```

## Monads

Monads are a natural extension to applicative functors. If you have a
value with a context `m a`

, how do you apply to it a function that
takes a normal a and returns a value with a context?

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

In Prelude, `IO`

, lists, and `Maybe`

are members of the monadic
classes.

```
-- infixl 1 >>=, >>
class Applicative m => Monad (m :: * -> *) where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
```

`>>`

, referred, to as bind, combines a Monad containing values of type
`a`

, and a function which operates on `a`

and returns a monad of type
`b`

.

`>>`

, also sometimes called *Mr. Pointy*, is used when the function
does not need the value of the first Monadic operator.

The precise meaning of bind depends on the monad. For example, in the
`IO`

monad, `x>>=y`

performs two actions sequentially, passing the
result of the first into the second. For the lists and `Maybe`

type,
these monadic operations can be understood in terms of passing zero or
more values from one calculation to the next.

The `do`

syntax provides a simple shorthand for chains of monadic
operations:

```
do e1 ; e2 = e1 >> e2
do p <- e1; e2 = e1 >>= (\v -> case v of p -> e2; _ -> fail "s")
```

The laws which govern `>>=`

and `return`

are:

```
return a >>= k = k a
m >>= return = m
xs >>= return . f = fmap f xs
m >>= (\x -> k x >>= h) = (m >>= k) >>= h
```

### Built in Monads

#### Maybe

```
-- treating Maybe as unctors
fmap (++"!") (Just "wisdom") -- Just "wisdom!"
fmap (++"!") Nothing -- Nothing
-- treating Maybe as Applicatives
Just (+3) <*> Just 3 -- Just 6
Nothing <*> Just "greed" -- Nothing
max <$> Just 3 <*> Just 6 -- Just 6
max <$> Just 3 <*> Nothing -- Nothing
-- Upgrading to Monads
(\x -> Just (x + 1)) 1 -- Just 2
applyMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b
applyMaybe Nothing f = Nothing
applyMaybe (Just x) f = f x
Just 3 `applyMaybe` \x -> Just (x + 1) -- Just 4
Nothing `applyMaybe` \x -> Just (x + 1) -- Nothing
-- applyMaybe is >>= for the Maybe monad
```

#### Lists

The monadic aspects of lists bring non-determinism into code in a clear and readable manner.

```
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
```

```
[3,4,5] >> = \x -> [x, -x]
-- [3, -3, 4, -4, 5, -5]
```

Non-determinism also includes support for failure. Here, the empty
list `[]`

is the equivalent of `Nothing`

, because it signifies the
absence of a result.

Just like with `Maybe`

values, we can chain several lists with `>>=`

:

```
[1,2] >>= \n -> ['a', 'b'] >>= \ch -> return (n,ch)
-- [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
do
n <- [1,2]
ch <- ['a', 'b']
return (n,ch)
```

The list `[1,2]`

gets bound to n, and `["a", "b"]`

gets bound to ch.
`return (n,ch)`

, takes the tuple, and makes the smallest possible list
that still presents (n,ch) as the result.

For lists, monadic binding involves joining together a set of
calculations for each value in the list. When used with lists, the
signature of `>>=`

becomes:

```
(>>=) :: [a] -> (a -> [b]) -> [b]
```

Given a list of `a`

’s and a function that maps an a onto a list of
`b`

’s, `>>=`

applies this function to each of the `a`

’s in the input
and returns the generated `b`

’s concatenated into a list. The return
function creates a singleton list.

The following two expressions are equivalent:

```
[(x,y) | x <- [1,2,3] , y <- [1,2,3], x /= y]
do x <- [1,2,3]
y <- [1,2,3]
True <- return (x /= y)
return (x,y)
```

### Using Monads

We first analyse this state monad, built around a state type `s`

that
looks like this:

```
data SM a = SM (S -> (a, S)) -- The monadic type
instance Monad SM where
-- defines state propogation
SM c1 >>= fc2 = SM (\s0 -> let (r, s1) = c1 s0
SM c2 = fc2 r
in
c2 s1)
return k = SM (\s -> (k, s))
-- extracts the state from the Monad
readSM :: SM S
readSM = SM (\s -> (s, s))
-- updates the state of the monad
updateSM :: (S -> S) -> SM () -- alters the state
updateSM f = SM (\s -> ((), f s))
-- run a computation in the SM monad
runSM :: S -> SM a -> (a, S)
runSM s0 (SM c) = c s0
```

`SM`

is defined to be a computation that implicitly carries a type
`s`

. `SM`

consists of functions that take a state and produce two
results: a returned value (of any type) and an updated state.

The instance declaration defines the ‘plumbing’ of the monad: how to sequence two computations and the definition of an empty computation.

Sequencing (`>>=`

) defines a computation (denoted by the constructor
`SM`

) that passes the initial state, `s0`

into `c1`

, then passes the
value coming out of this computation, `r`

, to the function that
returns the second computation, `c2`

. Finally, the state coming out of
`c1`

is passed into `c2`

and the overall result is the result of `c2`

.

Here `return`

doesn’t change the state at all; it only serves to
bring a value into the monad.

`readSM`

brings the state out of the monad for observation while
`updateSM`

allows the user to alter the state in the monad.

## Do Notation

Haskell’s do notation supports an imperative style of programming by providing syntactic sugar for chains of monadic expressions.

```
a >>= \x ->
b >>
c >>= \y ->
d
-- becomes:
do { x <- a
; b
; y <- c
; d
}
```

```
do e → e
do { e; stmts } → e >> do { stmts }
do { v <- e; stmts } → e >>= \v -> do { stmts }
do { let decls; stmts} → let decls in do { stmts }
```

```
routine :: Maybe Pole
routine = do
start <- return (0,0)
first <- landLeft 2 start
second <- landRight 2 first
landLeft 1 second
```