- In Haskell, functions are
*pure*:- Same argument ⟹ same result, there are no hidden dependencies
- The returned value is the only result
- There are no other effects that can change the result of the program

- Is this good or bad?
- + It helps keep your code clean and modular.
- + It's good for automated testing.
- - Limits what you can do with functions...

**int**f(**int**x) {**return**5*x; }**int**g() {**return**f(3); }- What does
`g()`

return?

**int**k=1;**int**f(**int**x) {**return**k*x; }**int**g() { k=5;**return**f(3); }- What does
`f(3)`

return? - Note that
`f`

has the same type as in the previous example.

**int**y=0;**int**f(**int**x) { y=x+1;**return**2*x; }**int**g() {**int**z=f(10);**return**y+z; }- What does
`g()`

return? - Note that
`f`

has the same type as in the previous examples.

**int**pageNr=0;**int**newPageNr() { pageNr++;**return**pageNr; }**void**startNewPage() { printf("\f--- Page %d ---\n",newPageNr()); }`newPage`

changes the state (has both extra input and extra output).`startNewPage`

changes the state and performs IO operations.

**int**f(**int**i) {**if**(i<0 || i+1>=size)**raise**BadArgument;**else return**(a[i]+a[i+1])/2; }**void**g(**int**i) {**try**printf("Answer: %d",f(i));**catch**(e) printf("Oops"); }- Many languages have exception handling.
- Note that
`f`

has the same type as in the previous examples.

All inputs and outputs have to be

*visible in the type*:Pure function: **Input****->****Output**Extra input: **Input****->****Extra****->****Output**Extra output: **Input****->**(**Extra**,**Output**)Changing the state: **Input****->****State****->**(**State**,**Output**)IO operations: **Input****->****IO****Output**Sometimes no result: **Input****->****Maybe****Output**Many results: **Input****->**[**Output**]- But will it be practical to write programs with functions of these types?

- Assume we want to define a function
`h`

that combines two functions`f`

and`g`

that both have additional effects. -- Pure functions:

`h``x`**=**`g`(`f``x`) -- Extra input:`h``x``e`**=**`g`(`f``x``e`)`e`

-- Extra outputhx=(o1<>o2,y2)where(o1,y1)=fx(o2,y2)=gy1-- Changing the state:hxs0=(s2,y2)where(s1,y1)=fxs0(s2,y2)=gy1s1

-- IO operations:hx=doy1<-fxy2<-gy1returny2-- Sometimes no result:hx=casefxofNothing->NothingJusty->gy-- Many results:hx=[y2|y1<-fx,y2<-gy1]

- It looks like a lot of extra code to deal with extra effects!
- This requires no extra code in other languages...

- Do we really want a pure functional language?
- It is not as bad as it looks!
- We could define operators to simplify things!
- Use the power of higher order functions!

- Instead of we had to write
`h``x`**=**`g`(`f``x`)`h``x`**=**(`o1``<>``o2`,`y2`)**where**(`o1`,`y1`)**=**`f``x`(`o2`,`y2`)**=**`g``y1`

- Can we define an operator that hides all the glue code?
`=<<``h``x`**=**`g``=<<``f``x`

- Instead of we had to write
`h``x`**=**`g`(`f``x`)`h``x`**=**(`o1``<>``o2`,`y2`)**where**(`o1`,`y1`)**=**`f``x`(`o2`,`y2`)**=**`g``y1`

- Can we define an operator that hides all the glue code?
`=<<``h``x`**=**`g``=<<``f``x`

- Yes! Solution:
`g``=<<``fx`**=**(`o1``<>``o2`,`y2`)**where**(`o1`,`y1`)**=**`fx`(`o2`,`y2`)**=**`g``y1`

- What about other effects?
- We will need different variants of the operator for different extra effects.
`=<<` - The different variants will have different types.
- Can we use overloading?
- To do that, we need make a method in a type class.
`=<<` - To do that, we factor out a common pattern from the different types.

- To do that, we need make

Taking another look at the types:

Type of effect Function type Pure function: **Input****->****Output**Extra input: **Input****->****Extra****->****Output**Extra output: **Input****->**(**Extra**,**Output**)Changing the state: **Input****->****State****->**(**State**,**Output**)IO operations: **Input****->****IO****Output**Sometimes no result: **Input****->****Maybe****Output**Many results: **Input****->**[**Output**]- Can we factor out a common pattern?

We can factor them like this:

Type of effect The common pattern The difference Pure function: **Input****->****M****Output**=**M**`a``a`Extra input: **Input****->****M****Output**=**M**`a`**Extra****->**`a`Extra output: **Input****->****M****Output**=**M**`a`(

**Extra**,`a`)Changing the state: **Input****->****M****Output**=**M**`a`**State****->**(**State**,`a`)IO operations: **Input****->****M****Output**=**M**`a`**IO**`a`Sometimes no result: **Input****->****M****Output**=**M**`a`**Maybe**`a`Many results: **Input****->****M****Output**=**M**`a`[

`a`]- In all cases it can be seen as a modification of the return type!

*Monadic programming*means using functions of type,**Input****->****M****Output**- for some type .
**M**

- for some type
- The type is the
**M***monad*. - The type of "monadic function application":
(

`=<<`)**::**(`a`**->****M**`b`)**->****M**`a`**->****M**`b`

- Compare with the type of pure function application:
(

`$`)**::**(`a`**->**`b`)**->**`a`**->**`b`

- Now let's put in a type class...
`=<<`

**class****Monad**`m`**where**`return`**::**`a`**->**`m``a`(`>>=`)**::**`m``a`**->**(`a`**->**`m``b`)**->**`m``b`-- ... (`=<<`)**::****Monad**`m`**=>**(`a`**->**`m``b`)**->**`m``a`**->**`m``b``f``=<<``x`**=**`x``>>=``f`- This allows us to write overloaded functions that work in any monad.
- There are many predefined monadic functions. Some are in
the prelude, there are more in the library module
**Control.Monad**. - Note that the type variable above ranges over types that take a parameter.
`m`

- The notation is translated into expressions using
**do**`>>=`- That's why it works for any monad!

- Example:
- ⟹
**do**`x`**<-**`m1`;`y`**<-**`m2``x`;`return`(`x``+``y`) - ⟹
`m1``>>=`(**\**`x`**->****do**`y`**<-**`m2``x`;`return`(`x``+``y`)) `m1``>>=`(**\**`x`**->**`m2``x``>>=`(**\**`y`**->**`return`(`x``+``y`)))

instanceMonadIO-- predefinedinstanceMonadGen-- from QuickCheckinstanceMonadParser-- from the Parsing module

**instance****Monad****Maybe****where**`return``x`**=****Just**`x`**Just**`x``>>=``f`**=**`f``x`**Nothing**`>>=`**_****=****Nothing**- In this instance:
`return`**::**`a`**->****Maybe**`a`(`>>=`)**::****Maybe**`a`**->**(`a`**->****Maybe**`b`)**->****Maybe**`b`

**instance****Monad**[]**where**`return``x`**=**[`x`]`xs``>>=``f`**=**[`y`**|**`x`**<-**`xs`,`y`**<-**`f``x`]- In this instance:
`return`**::**`a`**->**[`a`] (`>>=`)**::**[`a`]**->**(`a`**->**[`b`])**->**[`b`]

- The similarity is not a coincidence
[

`y`**|**`x`**<-**`xs`,`y`**<-**`f``x`]

⟺

**do**`x`**<-**`xs`;`y`**<-**`f``x`;`return``y`

- The list monad is the same as list comprehensions

- While using or the
`=<<`notation is enough, here are some more variants of function application that are also useful.**do**Operator Function Argument Result `$``a`**->**`b``a``b``<$>``a`**->**`b``m``a``m``b``<*>``m`(`a`**->**`b`)`m``a``m``b``=<<``a`**->**`m``b``m``a``m``b`

- One could imagine more combinations, but the operators above are all defined in the standard libraries...
- The operators and
`<$>`actually have their own type classes…`<*>`

**class****Functor**`f`**where**`fmap`**::**(`a`**->**`b`)**->**`f``a`**->**`f``b``f``<$>``x`**=**`fmap``f``x`- This is not just for monads, but for any data structure where it makes sense to apply a function to every element.
- It's a generalization of for lists. Compare:
`map` `map`**::**(`a`**->**`b`)**->**[`a`]**->**[`b`]`fmap`**::****Functor**`f`**=>**(`a`**->**`b`)**->**`f``a`**->**`f``b`

**instance****Functor****IO****instance****Functor****Gen**-- from QuickCheck**instance****Functor****Parser**- So we have
`fmap`**::**(`a`**->**`b`)**->****IO**`a`**->****IO**`b``fmap`**::**(`a`**->**`b`)**->****Gen**`a`**->****Gen**`b``fmap`**::**(`a`**->**`b`)**->****Parser**`a`**->****Parser**`b`

**instance****Functor****Maybe****where**`fmap``f`**Nothing****=****Nothing**`fmap``f`(**Just**`x`)**=****Just**(`f``x`)- In this instance
`fmap`**::**(`a`**->**`b`)**->****Maybe**`a`**->****Maybe**`b`

**instance****Functor**[]**where**`fmap`**=**`map`- In this instance
`fmap`**::**(`a`**->**`b`)**->**[`a`]**->**[`b`]

**class****Functor**`f`**=>****Applicative**`f`**where**`pure`**::**`a`**->**`f``a`(`<*>`)**::**`f`(`a`**->**`b`)**->**`f``a`**->**`f``b`- There are more instances in the class than in the
**Applicative**class.**Monad**- is easier to implement than
`<*>`.`=<<` - is the same as
`pure`. They both exist for historical reasons.`return`

**instance****Applicative****IO****instance****Applicative****Gen**-- from QuickCheck**instance****Applicative****Parser**- So we have
(

`<*>`)**::****IO**(`a`**->**`b`)**->****IO**`a`**->****IO**`b`(`<*>`)**::****Gen**(`a`**->**`b`)**->****Gen**`a`**->****Gen**`b`(`<*>`)**::****Parser**(`a`**->**`b`)**->****Parser**`a`**->****Parser**`b`

**instance****Applicative**[]**where**`pure``x`**=**[`x`]`fs``<*>``xs`**=**[`f``x`**|**`f`**<-**`fs`,`x`**<-**`xs`]- In this instance
`pure`**::**`a`**->**[`a`] (`<*>`)**::**[`a`**->**`b`]**->**[`a`]**->**[`b`]

**instance****Applicative****Maybe****where**`pure``x`**=****Just**`x`**Just**`f``<*>`**Just**`x`**=****Just**(`f``x`)**_**`<*>`**_****=****Nothing**- In this instance
`pure`**::**`a`**->****Maybe**`a`(`<*>`)**::****Maybe**(`a`**->**`b`)**->****Maybe**`a`**->****Maybe**`b`

- We have seen a few examples where using simplifies the code:
`<$>` `rNumeric`**::****Gen****Rank**`rNumeric`**=****do**`n`**<-**`choose`(2,10)`return`(**Numeric**`n`)`rNumeric`**=****Numeric**`<$>``choose`(2,10)`number`**::****Parser****Integer**`number`**=****do**`ds`**<-**`oneOrMore``digit``return`(`read``ds`)`number`**=**`read``<$>``oneOrMore``digit`

- Here are some examples where using simplified the code:
`<*>` `rCard`**::****Gen****Card**`rCard`**=****do**`s`**<-**`rSuit``r`**<-**`rRank``return`(**Card**`s``r`)`rCard`**=****Card**`<$>``rSuit``<*>``rRand``oneOrMore`**::****Parser**`item`**->****Parser**[`item`]`oneOrMore``item`**=****do**`i`**<-**`item``is`**<-**`zeroOrMore``item``return`(`i`**:**`is`)`oneOrMore``item`**=**(**:**)`<$>``item``<*>``zeroOrMore``item`

- Starting with GHC 7.10, is a superclass of
**Applicative**,**Monad****class****Applicative**`m`**=>****Monad**`m`**where**-- ...

- so to make a instance you also have to make an
**Monad**instance (and a**Applicative**instance).**Functor** - This is easy using standard library functions:
- =
`pure``return` - =
(

`<*>`)`ap` - =
`fmap``liftM`