## Essential Haskell

I suggest you to skim this part. Think of it like a reference. Haskell has a lot of features. Many informations are missing here. Get back here if notation feels strange.

I use the `⇔`

symbol to state that two expression are equivalent.
It is a meta notation, `⇔`

does not exists in Haskell.
I will also use `⇒`

to show what is the return of an expression.

### Notations

##### Arithmetic

`3 + 2 * 6 / 3 ⇔ 3 + ((2*6)/3)`

##### Logic

```
True || False ⇒ True
True && False ⇒ False
True == False ⇒ False
True /= False ⇒ True (/=) is the operator for different
```

##### Powers

```
x^n for n an integral (understand Int or Integer)
x**y for y any kind of number (Float for example)
```

`Integer`

have no limit except the capacity of your machine:

```
4^103
102844034832575377634685573909834406561420991602098741459288064
```

Yeah!
And also rational numbers FTW!
But you need to import the module `Data.Ratio`

:

```
$ ghci
....
Prelude> :m Data.Ratio
Data.Ratio> (11 % 15) * (5 % 3)
11 % 9
```

##### Lists

```
[] ⇔ empty list
[1,2,3] ⇔ List of integral
["foo","bar","baz"] ⇔ List of String
1:[2,3] ⇔ [1,2,3], (:) prepend one element
1:2:[] ⇔ [1,2]
[1,2] ++ [3,4] ⇔ [1,2,3,4], (++) concatenate
[1,2,3] ++ ["foo"] ⇔ ERROR String ≠ Integral
[1..4] ⇔ [1,2,3,4]
[1,3..10] ⇔ [1,3,5,7,9]
[2,3,5,7,11..100] ⇔ ERROR! I am not so smart!
[10,9..1] ⇔ [10,9,8,7,6,5,4,3,2,1]
```

##### Strings

In Haskell strings are list of `Char`

.

```
'a' :: Char
"a" :: [Char]
"" ⇔ []
"ab" ⇔ ['a','b'] ⇔ 'a':"b" ⇔ 'a':['b'] ⇔ 'a':'b':[]
"abc" ⇔ "ab"++"c"
```

Remark: In real code you shouldn't use list of char to represent text. You should mostly use`Data.Text`

instead. If you want to represent stream of ASCII char, you should use`Data.ByteString`

.

##### Tuples

The type of couple is `(a,b)`

.
Elements in a tuple can have different type.

```
-- All these tuple are valid
(2,"foo")
(3,'a',[2,3])
((2,"a"),"c",3)
fst (x,y) ⇒ x
snd (x,y) ⇒ y
fst (x,y,z) ⇒ ERROR: fst :: (a,b) -> a
snd (x,y,z) ⇒ ERROR: snd :: (a,b) -> b
```

##### Deal with parentheses

To remove some parentheses you can use two functions: `($)`

and `(.)`

.

```
-- By default:
f g h x ⇔ (((f g) h) x)
-- the $ replace parenthesis from the $
-- to the end of the expression
f g $ h x ⇔ f g (h x) ⇔ (f g) (h x)
f $ g h x ⇔ f (g h x) ⇔ f ((g h) x)
f $ g $ h x ⇔ f (g (h x))
-- (.) the composition function
(f . g) x ⇔ f (g x)
(f . g . h) x ⇔ f (g (h x))
```

Exercise:

Define correctly the `selectWin`

X functions using only `fst`

, `snd`

and `.`

in order to show `win`

on each line.

```
selectWin1 = undefined
main = do
print $ selectWin1 (1,"win") -- should return "win"
```

```
selectWin2 = undefined
main = do
print $ selectWin2 (("win","no"),"not this one")
```

```
selectWin3 = undefined
main = do
print $ selectWin3 (1,("no",("win","almost")))
```

```
selectWin1 = snd
selectWin2 = fst . fst
selectWin3 = fst . snd . snd
main = do
putStrLn $ selectWin1 (1,"win")
putStrLn $ selectWin2 (("win","no"),"not this one")
putStrLn $ selectWin3 (1,("no",("win","almost")))
```

### Useful notations for functions

Just a reminder:

```
x :: Int ⇔ x is of type Int
x :: a ⇔ x can be of any type
x :: Num a => a ⇔ x can be any type a
such that a belongs to Num type class
f :: a -> b ⇔ f is a function from a to b
f :: a -> b -> c ⇔ f is a function from a to (b→c)
f :: (a -> b) -> c ⇔ f is a function from (a→b) to c
```

Defining the type of a function before its declaration isn't mandatory. Haskell infers the most general type for you. But it is considered a good practice to do so.

*Infix notation*

```
square :: Num a => a -> a
square x = x^2
```

Note `^`

use infix notation.
For each infix operator there its associated prefix notation.
You just have to put it inside parenthesis.

```
square' x = (^) x 2
square'' x = (^2) x
```

We can remove `x`

in the left and right side!
It's called η-reduction.

`square''' = (^2)`

Note we can declare function with `'`

in their name.
Here:

`square`

⇔`square'`

⇔`square''`

⇔`square '''`

*Tests*

An implementation of the absolute function.

```
absolute :: (Ord a, Num a) => a -> a
absolute x = if x >= 0 then x else -x
```

Note: the `if .. then .. else`

Haskell notation is more like the
`¤?¤:¤`

C operator. You cannot forget the `else`

.

Another equivalent version:

```
absolute' x
| x >= 0 = x
| otherwise = -x
```

Notation warning: indentation is

importantin Haskell. Like in Python, a bad indentation could break your code!

```
square :: Num a => a -> a
square x = x^2
square' x = (^) x 2
square'' x = (^2) x
square''' = (^2)
absolute :: (Ord a, Num a) => a -> a
absolute x = if x >= 0 then x else -x
absolute' x
| x >= 0 = x
| otherwise = -x
-- show
main = do
print $ square 10
print $ square' 10
print $ square'' 10
print $ square''' 10
print $ absolute 10
print $ absolute (-10)
print $ absolute' 10
print $ absolute' (-10)
-- /show
```

Exercise:

Modify the following code in order to use only prefix notation:

```
f x y = x*x + y*y
main = print $ f 2 4
```

```
f x y = (+) ((*) x x) ((*) y y)
main = print $ f 2 4
```