Interactive code snippets not yet available for SoH 2.0, see our Status of of School of Haskell 2.0 blog post

# Haskell Fast & Hard (Part 2)

11 Apr 2013

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")))``````

### 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 important in 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``````

continue to next part