# Haskell

## Table of Contents

## Whatever

- Checkout book "Learn Haskell for the Greater Good"
- Checkout this paper about the great "Selection Monad", which provides a DSL for selection algorithms.

## Features

- Lazyily evaluated

## Running

`ghci`

- interactive

Gives you a nice REPL to work with.
It is quite similar to how the `scala`

REPL works:

`:load`

to load files (these do not need a`main`

as we do for compiling, again like`scala`

REPL)`:r`

to run the already loaded files

`ghc`

- compiling into binary executable

Works very much like `gcc`

. You can simply type `ghc Main.hs`

or provide output arguments and so on: `ghc -o Main.o -c Main.hs`

.

And like with `C`

, `Haskell`

expects a `main`

function when compiling
into a binary.

## Basics

import Data.List

addEx = 5 + 4 subEx = 5 - 4 multEx = 5 * 4 divEx = 5 / 4

(addEx, subEx, multEx, divEx) -- Tuple!

To inspect the type of anything, simply use the `:t`

.

```
:t truncate
```

### Infix operators

primes = [1, 3, 5] (elem 1 primes, 1 `elem` primes) -- (regular, infix op)

### Lists

- Elements all need to have same datatype

primeNumbers = [3, 5, 7, 11] -- a List morePrime = primeNumbers ++ [13, 17, 19, 23, 29] -- List concatenation favNums = 2 : 7 : 21 : 66 : [] -- conj operator favNums

[2,7,21,66]

listTimes2 = [x * 3 | x <- [1..10]] listTimes2

listTimes2 = [x * 3 | x <- [1..10], x * 3 <= 20] listTimes2

divisBy9 = [x | x <- [1..100], x `mod` 9 == 0] divisBy9

##### Indexing

```
[1, 2, 3] !! 1
```

#### Infinite lists

evensUpTo20 = takeWhile (<= 20) [2, 4..] evensUpTo20

#### List comprehension

multTable = [[x * y | y <- [1..5]] | x <- [1..5]] multTable

### Tuples

- Does
**not**require elements to have same type

randTuple = (1, "Random tuple") fst randTuple

names = ["Bob", "Mary"] addresses = ["This road", "Another road"] zip names addresses

### Functions

Functions in `Haskell`

can be defined in multiple ways.

#### With type declaration

Functions with declarations take the form

-- funcName param1 param2 = operations (return value) ""

When we're **not** in the REPL, we can declare typed functions on multiple
lines, as follows:

addMe :: Int -> Int -> Int addMe x y = x + y

But when we're in the REPL, we need to do both the type declaration and
definition of function on the *same* line:

let addMeTyped :: Int -> Int -> Int; addMeTyped x y = x + y addMeTyped 3.1 2.2

```
addMeTyped 3 2
```

```
:t addMeTyped
```

#### Without type declaration

addMeAny x y = x + y (addMeAny 4.0 3.5, addMeAny 4 3)

(7.5,7)

```
:t addMeAny
```

#### Using `let`

let a = 7 let getTriple x = x * 3 getTriple a

let getDouble x = x * y where y = 2 getDouble 3

```
where ... = syntax has precedence over the arguments, so if you were to
write =let getDouble x = x * 2 where x = 3
```

, calling `getDouble 1`

would
actually return `3 * 2`

not `1 * 2`

.

#### Using `do`

This is a very convienent way of chaining a bunch of operations.

main = do putStrLn "What's your name? " name <- getLine putStrLn ("Hello " ++ name)

If you were to compile this using `ghc -o Name.o -c Name.hs`

and then run the
binary executable, you'll be prompted for your name, woooo!

What is very important about the `do`

syntax is the following:

`<-`

extracts the the value from the monad`let`

does not extract the value

f = do y <- Just 1 -- 1 let x = Just 1 -- Just 1 y

#### Pattern matching

whatAge :: Int -> String whatAge 16 = "You can drive" whatAge 18 = "You can vote" whatAge 21 = "You're an adult, sort of" whatAge _ = "I don't know what you are!" -- could be any variable, say `x` and then use `x` inside the function ""

#### Guards

-- guards isOdd :: Int -> Bool isOdd n | n `mod` 2 == 0 = False | otherwise = True

let getListItems :: [Int] -> String; getListItems [] = "Your list is empty" getListItems [x] = "Only got one element: " ++ show x -- `show` is just stringifing `x` getListItems [x, y] = "Got two elems: " ++ show x ++ " and " ++ show y -- similar to binding the entire match in Scala getListItems three@[x, y, z] = "Got these three elems " ++ show three getListItems (x:xs) = "First is " ++ show x ++ " and the rest is " ++ show xs getListItems [1, 2, 3] -- "Got these three elems [1, 2, 3]" getListItems [1, 2, 3, 4] -- "First is 1 and the rest is [2, 3, 4]"

#### Higher order functions

Simply passing functions to functions.

areStringsEq :: [Char] -> [Char] -> Bool areStringsEq [] [] = True areStringsEq (x: xs) (y: ys) = x == y && areStringsEq xs ys areStringsEq _ _ = False

#### Lambdas

-- lambdas dbl1To10 = map (\x -> x * 2) [1..10] dbl1To10

### Conditionals

doubleEvenNumber y = if y `mod` 2 /= 0 then y else y * 2

getClass :: Int -> String getClass n = case n of 5 -> "Go to Kindergarten" _ -> "Go home"

### Modules

##### Creating a module

module SampFunctions (getClass, doubleEvenNumbers) where

##### Importing a module

import SampFunctions

### Enumeration

Haskell has something called a `DataType`

, which we can create custom ones
for ourselves.

data BaseballPlayer = Pitcher | Catcher | Infielder | Outfield deriving Show -- Custom stuff data Customer = Customer String String Double deriving Show tomSmith :: Customer tomSmith = Customer "Tom Smith" "123 Main" 20.50 getBalance :: Customer -> Double getBalance (Customer _ _ b) = b -- "Multitypes" ? data Shape = Circle Float Float Float | Rectangle Float Float Float Float area :: Shape -> Float area (Circle _ _ r) = pi * r ^ 2 -- `$` simply allows us to remove the parenthesis area (Rectangle x y x2 y2) = (abs $ x2 - x) * (abs (y2 - y))

### Dot operator

This is simply *function composition*.

```
:t putStrLn
```

```
:t show
```

:t putStrLn . show

putStrLn . show $ 1 + 2

### Type classes

I think these are like `trait`

in `Rust`

.

:t (+) -- (+) :: Num a => a -> a -> a

data Employee = Employee { name :: String, vv position :: String, idNum :: Int } deriving (Eq, Show) samSmith1 = Employee {name = "Sam", position = "1", idNum = 1} samSmith2 = Employee {name = "Sam", position = "1", idNum = 1} samSmith1 == samSmith2 -- True

data ShirtSize = S | M | L instance Eq ShirtSize where S == S = True M == M = True L == L = True _ == _ = False S `elem` [S, M, L] -- True

##### Classes

class MyEq a where areEqual :: a -> a -> Bool instance MyEq ShirtSize where areEqual S S = True areEqual M M = True areEqual L L = True -- areEqual S S => True

### I/O

writeToFile = do theFile <- openFile "test.txt" WriteMode hPutStrLn theFile ("Random line of text") hClose theFile readFromFile = do theFile2 <- openFile "test.txt" ReadMode contents <- hGetContets theFile2 putStr contents hClose theFile2

## Concepts

### Monad

#### Examples of monads

`Maybe x`

is a way of defining a "box" for some value which can either
be a value of type `x`

or `Nothing`

. This is basically the same as
`Option[T]`

in Scala. The interesting thing here is that we can define
`Maybe`

in a *Monadic* manner.

:t (=<<)

## Book: Learn You a Haskell for Great Good

### Making our own Types and Typeclasses

#### Recursive data structures

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq) -- creates a simple node without any children/subtrees singleton :: a -> Tree a singleton x = Node x EmptyTree EmptyTree -- inserting into the tree treeInsert :: (Ord a) => a -> Tree a -> Tree a treeInsert x EmptyTree = singleton x treeInsert x (Node a left right) | x == a = Node x left right -- same value => return same tree | x < a = Node a (treeInsert x left) right -- create new tree with `a` inserted in L | x > a = Node a left (treeInsert x right) -- create new tree with `a` inserted in R -- checking if element exists in `Tree` treeElem :: (Ord a) => a -> Tree a -> Bool treeElem x EmptyTree = False treeElem x (Node a left right) | x == a = True | x < a = treeElem x left | x > a = treeElem x right

-- building the from a `List` tree using `foldr` let nums = [8,6,4,1,7,3,5] let tree = foldr treeInsert EmptyTree nums tree

```
(8 `treeElem` tree, treeElem 9999 tree)
```

(True,False)

#### Typeclasses 102

- Types
- defined using the
`data`

keyword. - Typeclasses
like interaces. It defines some behavior and then types that can behave in that way are made instances of that typeclass.

Here we define a "behavior"

`Eq`

for some type`a`

.class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x == y = not (x /= y) -- You're probably like "WHAT?! RECURSIVE DEFINITION ALERT!" x /= y = not (x == y) -- Just keep readin' bro.

Let's implement this behavior for some custom type

`TrafficLight`

.data TrafficLight = Red | Yellow | Green instance Eq TraffigLight where Red == Red = True -- here we're just defining the behavior of `==` Yellow == Yellow = True Green == Green = True _ == _ = False

But what about

*inequality*?! Relax brooo, we have defined`(/`

)= to be the negation of the equality, thus by defining equality we've implicitly defined inequality! Woah! Is it just me or is it the world spinning slightly?

#### The Functor Typeclass

**TLDR:** `Functor`

is for things which can be mapped over. Or rather
things which implement `fmap`

, allowing us to map functions over
this "thing" / "box" or whatever.

fmap (* 2) [2, 3, 4]

The `Functor`

class is implemented as follows:

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

`f`

is not a*concrete*type (e.g.`Int`

) but a*type constructor*that takes one type parameter`fmap`

takes a function from one type to another and a functor applied with one type and returns a functor applied with another type.

An example of a `Functor`

is a list!

instance Functor [] where fmap = map

where `map`

has the following signature

```
:t map
```

See? For lists `fmap`

is simply `map`

.

`fmap`

only takes one argument! This means that if we have some constructor `f`

which takes multiple arguments, then we need to partially define it, i.e. replace
`f`

with `(Whatever a b ... )`

, and define `fmap`

using, say, pattern matching.
Yah feel me?

Types which can acts a "box" can be `Functors`

. For example,
`Maybe`

is not a concrete type, but `Maybe a`

is!

instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing

Let's try doing this for our `Tree`

structure!

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq) -- creates a simple node without any children/subtrees singleton :: a -> Tree a singleton x = Node x EmptyTree EmptyTree -- inserting into the tree treeInsert :: (Ord a) => a -> Tree a -> Tree a treeInsert x EmptyTree = singleton x treeInsert x (Node a left right) | x == a = Node x left right -- same value => return same tree | x < a = Node a (treeInsert x left) right -- create new tree with `a` inserted in L | x > a = Node a left (treeInsert x right) -- create new tree with `a` inserted in R -- checking if element exists in `Tree` treeElem :: (Ord a) => a -> Tree a -> Bool treeElem x EmptyTree = False treeElem x (Node a left right) | x == a = True | x < a = treeElem x left | x > a = treeElem x right instance Functor Tree where fmap f EmptyTree = EmptyTree fmap f (Node a left right) = Node (f a) (fmap f left) (fmap f right)

Just to remind us what the value of the `tree`

variable is:

let nums = [8,6,4,1,7,3,5] let tree = foldr insertTree EmptyTree nums tree

fmap (* 2) tree -- (+) takes 2 args => (+ 1) defines a partial func taking 1 arg! MAGIC!

#### Kinds and some type-foo

- A type has kind
`*`

, then it's a*concrete*type - Inspect kinds using
`:k`

:k Int

Int :: *

:k Maybe -- constructor which takes one concrete type to another concrete type

Maybe :: * -> *

### Functors, Applicative Functors and Monoids

#### Applicative functors

- Found in
`Control.Applicative`

- "Beefed up"
`Functors`

class (Functor f) => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b -- it's an infix operator

A better way of thinking about `pure`

would be to say that it takes a value
and puts it in some sort of default (or `pure`

) contextâ€”a minimal context
that still yields that value.

The `<*>`

function is really interesting. It has a type declaration of
`f (a -> b) -> f a -> f b`

. Does this remind you of anything? Of course,
`fmap :: (a -> b) -> f a -> f b`

. It's a sort of a beefed up `fmap`

.
Whereas `fmap`

takes a function and a functor and applies the function
inside the functor, `<*>`

takes a functor that has a function in it
and another functor and sort of extracts that function from the first functor
and then maps it over the second one. When I say extract, I actually sort of
mean run and then extract, maybe even sequence.

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

Applicative functors and the applicative style of doing `pure f <*> x <*> y <*> ...`

allow us to take a function that expects parameters that aren't necessarily
wrapped in functors and use that function to operate on several values that
are in functor contexts. The function can take as many parameters as we want,
because it's always partially applied step by step between occurences of `<*>`

.

Lists (actually the list type constructor, `[]`

) are applicative functors.
What a suprise! Here's how `[]`

is an instance of `Applicative`

:

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

##### Examples

[(* 2)] <*> [1, 2, 3]

(* 2) <$> [1, 2, 3]

## Appendix A: Files

import Data.List import System.IO -- Pattern matching whatAge :: Int -> String whatAge 16 = "You can drive" whatAge 18 = "You can vote" whatAge 21 = "You're an adult, sort of" whatAge _ = "I don't know what you are!" -- factorial factorial :: Int -> Int factorial 0 = 1 factorial n = n * factorial(n - 1) -- Function guards isOdd :: Int -> Bool isOdd n | n `mod` 2 == 0 = False | otherwise = True isEven n = n `mod` 2 == 0 -- another guard example batAvgRating :: Double -> Double -> String batAvgRating hits atBats | avg <= 0.200 = "Terrible" | avg <= 0.280 = "OK" | otherwise = "Good" where avg = hits / atBats -- pattern matching over a list getListItems :: [Int] -> String getListItems [] = "Your list is empty" getListItems [x] = "Only got one element: " ++ show x -- `x.toString()` getListItems [x, y] = "Got two elems: " ++ show x ++ " and " ++ show y getListItems three@[x, y, z] = "Got these three elems " ++ show three -- similar to binding the entire match in Scala getListItems (x:xs) = "First is " ++ show x ++ " and the rest is " ++ show xs -- Higher order functions times4 :: Int -> Int times4 x = 4 * x listTimes4 xs = map times4 xs multBy4 :: [Int] -> [Int] -- will do exactly the same as `listTimes4` multBy4 [] = [] multBy4 (x:xs) = times4 x : multBy4 xs -- one by one call `times4` -- really neat recursion example areStringsEq :: [Char] -> [Char] -> Bool areStringsEq [] [] = True areStringsEq (x: xs) (y: ys) = x == y && areStringsEq xs ys areStringsEq _ _ = False -- passing function to function doMult :: (Int -> Int) -> Int doMult func = func 3 num3times4 = doMult times4 -- lambdas dbl1To10 = map (\x -> x * 2) [1..10] -- conditionals doubleEvenNumber y = if y `mod` 2 /= 0 then y else y * 2 getClass :: Int -> String getClass n = case n of 5 -> "Go to Kindergarten" _ -> "Go home" -- Enums data BaseballPlayer = Pitcher | Catcher | Infielder | Outfield deriving Show barryBonds :: BaseballPlayer -> Bool barryBonds Outfield = True -- Custom stuff data Customer = Customer String String Double deriving Show tomSmith :: Customer tomSmith = Customer "Tom Smith" "123 Main" 20.50 getBalance :: Customer -> Double getBalance (Customer _ _ b) = b -- "Multitypes" ? data Shape = Circle Float Float Float | Rectangle Float Float Float Float area :: Shape -> Float area (Circle _ _ r) = pi * r ^ 2 area (Rectangle x y x2 y2) = (abs $ x2 - x) * (abs (y2 - y)) -- `$` simply allows us to remove the parenthesis data Employee = Employee { name :: String, position :: String, idNum :: Int } deriving (Eq, Show) samSmith1 = Employee {name = "Sam", position = "1", idNum = 1} samSmith2 = Employee {name = "Sam", position = "1", idNum = 1} data ShirtSize = S | M | L instance Eq ShirtSize where S == S = True M == M = True L == L = True _ == _ = False -- Classes class MyEq a where areEqual :: a -> a -> Bool instance MyEq ShirtSize where areEqual S S = True areEqual M M = True areEqual L L = True