# A Quick Look at Haskell

## 1 Environment

The most used compiler is GHC (debian package `ghc`, `ghc-doc`).

Haskell projects are typically built and packaged using Cabal (`cabal-install`).

There is an online package repository called Hackage.

## 2 Types

```"Hello " ++ " World"
```

is an expression. Its value is

```"Hello World"
```

Its type is

```String
```

Types are declared using the reserved operator `::` (read as "has type")

```xs = "Hello World" :: String
```

Here `xs` is a variable.

Variables and types names are case sensitive. Variable names begin with a lowercase character and type names begin with an uppercase character.

Type declarations are optional. In their absence, Haskell will infer the types. If it can't, you'll be asked to provide them.

## 3 Functions

Defining and calling functions is very simple

```addTwoLengths :: String -> String -> Int
addTwoLengths xs ys = length xs + length ys
```

A function can be defined for different arguments (the order in which the definitions are written is important)

```fac :: Int -> Int
fac 1 = 1
fac n = n * fac (n - 1)
```

### 3.1 Let

We can define local variables with `let``in`

```squaredDistance :: Int -> Int -> Int -> Int -> Int
squaredDistance x1 y1 x2 y2 =
let dx = x1 - x2
dy = y1 - y2
in dx ^ 2 + dy ^ 2
```

### 3.2 Partial application

A function can be partially applied, creating a new function

```sdFrom11 :: Int -> Int -> Int
sdFrom11 = squaredDistance 1 1

sdFrom11 4 4 :: Int
```

### 3.3 Composition

Two functions can be composed, creating a new function

```f = fac . length :: String -> Int
```

is the same as

```f n = fac (length n) :: String -> Int
```

### 3.4 Anonymous functions

We can define an anonymous function (lambda) with `\args` `->` `body`

```doubleLength = (\n -> n * 2) . length
```

### 3.5 Higher-order functions

It's possible to pass functions as arguments to functions and have functions return functions.

For example, `map` transforms a list by applying a function to every element.

```map (\n -> n + 1) [1,2,3]
```
```        ┌-<-<-<-<-<-┐
|           |
v           |

map :: (a -> b) -> [a] -> [b]

^^^^^^^^    ^^^    ^^^--- [2,3,4]
|         |
|         └--- [1,2,3]
\n -> n + 1
```

## 4 Algebraic Data Types

### 4.1 Sum types

The simplest example of a sum type is

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

Bool value is either `True` or `False`.

```x = True :: Bool
```

### 4.2 Product types

A product type is defined as

```data Person = Person String Int

^^^^^^   ^^^^^^ ^^^^^^ ^^^
|        |      |     |
|        |      └-----┴----- data constructor parameters
|        |
|        └-- data constructor
|
└-- type constructor
```

The `Person` on the left side is the type constructor. The `Person` on the right side is the data constructor. These don't have to have the same name, but they often do, to the chagrin of Haskell newbies everywhere.

To create a value of type `Person`, use the `Person` data constructor:

```p :: Person
p = Person "Morty" 22
```

### 4.3 Named data constructor parameters

Data constructor parameters can be named

```data Person = Person
{ name :: String
, age  :: Int
}
```

then an alternative way to create a `Person` is to write

```p = Person { name = "Morthy"
, age  = 22
}
```

### 4.4 Type constructor parameters

Type constructors can have parameters

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

where `a` is a type.

```greeting = Just "Hello" :: Maybe String
name     = Nothing      :: Maybe String
```

### 4.5 Compound example

For example, a ship may or may not have a captain

```data Ship = Ship
{ shipName :: String
, captain  :: Maybe Person
}
```

We can make a Ship with one

```s1 = Ship { shipName = "Queen Elizabeth 2"
, captain = Just ( Person "William Cooper" 50 )
}
```

And one without

```s2 = Ship { shipName = "Dinghy"
, captain = Nothing }
}
```

### 4.6 Data constructor parameter namespace

In the above example, `Person` had a `name` parameter, but `Ship` had a `shipName` parameter. This is because data constructor parameters share one namespace and cannot be reused in different data types. And that's because…

### 4.7 Data constructor named parameters are functions

These are automatically generated for you

```name :: Person -> String
age  :: Person -> Int

shipName :: Ship -> Maybe String
captain  :: Ship -> Maybe Person
```

Different functions (in the same module) can't have the same name.

### 4.8 Updating values with named constructor parameters

We can take an existing data type with named constructor parameters and update it. For example, to remove the captain from `s1` above

```s3 = s1 { captain = Nothing }
```

This creates a new copy of `s1`, `s3`, changing the parameters supplied.

### 4.9 Recursive data types

data type definitions can be recursive

```data List a = Nil
| Append a (List a)
```

a `List` of `a` is then either `Nil` (empty list) or an element of type `a` appended to a `List` of type `a`.

```l :: List Int
l = Append 1 (Append 2 (Append 3 (Append 4 Nil)))
```

## 5 Lists

Lists are a built-in recursive data type. They're constructed with the cons operator "`:`"

```1 : ( 2 : ( 3 : ( 4 : [] )))
```

Haskell provides an easier way to write the above

```[1, 2, 3, 4] :: [Int]
```

A `String` is a list of `Char`

```s = "Hello World" :: [Char]
```

## 6 Tuples

A tuple is a fixed size container. Unlike lists, a tuple may contain different types

for example

```("Proxima Centauri", 3, 4, 5) :: (String, Int, Int, Int)
```

## 7 If and case

`if``then``else` … is an expression. The `else` is mandatory (what value would the expression evaluate to if it wasn't?)

```describeIntSign :: Int -> String
describeIntSign n =
if n > 0
then "positive"
else "negative"
```

`case``of` … is also an expression, but a bit more general than `if`.

```describeInt :: Int -> String
describeInt n =
case n of
0 -> "zero"
1 -> "one"
2 -> "two"
_ -> "I don't know that number"
```

## 8 Deconstructing values

Data type values can be deconstructed with pattern matching in function arguments

```data Person = Person
{ name :: Maybe String
, age  :: Int
}

nonsense :: Person -> Int
nonsense (Person  Nothing a) = a
nonsense (Person (Just n) a) = length n + a
```

here `n` and `a` will be locally bound to `name` (when it isn't `Nothing`) and `age` of the person.

We can also pattern match in case expressions

```case p of
Person  Nothing a -> "This person doesn't have a name"
Person (Just n) a -> "This person's name is " ++ n
```

and let expressions

```let (Person _ a) = p in a + 1
```

use `_` to indicate that you don't care about a parameter.

Lists and tuples can also be pattern matched.

```headIntList :: [Int] -> Int

^^^^^^^^^^
|
recall, a list is an element appended (:'ed) to the rest of the list

swapPair :: (Int, Int) -> (Int, Int)
swapPair (x, y) = (y, x)
```

## 9 Parametric polymorphism

Defining a new function for each type of list like above would be silly. Haskell allows us to write generic/polymorphic functions.

```         ┌-- type variables, a is any type
|
├-----┐
|     |
v     v

swap :: (a, b) -> (b, a)
swap (a, b) = (b, a)
```

type variables are always lowercase.

## 10 Typeclasses

Typeclasses allow you to overload functions

```class Eq a where
(==) :: a -> a -> Bool
```

types are instances of typeclasses

```instance Eq Char where
(==) = ...
```

### 10.1 Standard typeclasses

typeclass functions
Eq `(==)`, `(/=)`
Ord `(<)`, `(<=)`, `(>=)`, `(>)`, `max`, `min`
Enum `succ`, `pred`, `toEnum`, `fromEnum`, `enumFrom`, `enumFromThen`, `enumFromTo`, `enumFromThenTo`
Num `(+)`, `(-)`, `(⋆)`, `negate`, `abs`, `signum`, `fromInteger`
Real `toRational`
Integral `quot`, `rem`, `div`, `mod`, `quotRem`, `divMod`, `toInteger`
Fractional `(/)`, `recip`, `fromRational`
Floating `pi`, `exp`, `log`, `sqrt`, `(⋆⋆)`, `logBase`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `sinh`, `cosh`, `tanh`, `asinh`, `atanh`
RealFrac `properFraction`, `truncate`, `round`, `ceiling`, `floor`
RealFloat `floatRadix`, `floatDigits`, `floatRange`, `decodeFloat`, `encodeFloat`, `exponent`, `significand`, `scaleFloat`, `isNaN`, `isInfinite`, `isDenormalized`, `isIEEE`, `isNegativeZero`, `atan2`
Monad `(>>=)`, `(>>)`, `return`, `fail`
Functor `fmap`

### 10.2 Automatic deriving

Haskell can automatically derive some typeclass instances for your data types (restrictions may apply). E.g.

```data Person = Person String Int
deriving Eq

p1 = Person "Rick" 50

p2 = Person "Morty" 12

p1 == p2 :: Bool
```

`Show` and `Read` are two important typeclasses. They implement `show` and `read` and can be automatically derived.

```show :: Show a => a -> String
```

That is, for types with a `Show` instance, `show` will turn the value into a `String`. For types with a `Read` instance, `read` will turn the `String` into the value of type `a`

```data Person = Person String Int

p1 = read "Person \"Rick\" 50" :: Person

show p1 :: String
```

You should not use `read` unless you know that the string is valid. An invalid string will cause a runtime error.

for inputs that may fail to parse, use `readMaybe`

```Text.Read.readMaybe :: Read a => String -> Maybe a
```

## 11 IO

### 11.1 Example: Echoing input line

Understanding how IO works in Haskell requires an unusual amount of background knowledge compared to other programming languages. It's best to begin with an example.

Haskell executables begin with the main function.

```main :: IO ()
main = getLine >>= putStrLn
```

The types of these functions (often called actions) are

```getLine  :: IO String
putStrLn :: String -> IO ()
```

`(>>=)` chains them together

```(>>=) :: IO a -> (a -> IO b) -> IO b

^^^^    ^^^^^^^^^^^    ^^^^
|          |          |
getLine --┘          |          |
|          └-- main
putStrLn ---┘
```

### 11.2 Example: Guess the number

What if we want to chain together two `IO a` actions like `putStrLn`? Replace the second one with a lambda that ignores its argument.

```putStrLn "Hello"    >>=    \_ -> putStrLn "World"

^^^^^^^^^^^^^^^^           ^^^^^^^^^^^^^^^^^^^^^^
|                              |
IO a                         a -> IO b
```

We can make a "guess the number" game with these functions (and `randomRIO`)

```import Text.Read
import System.Random

guessGame :: Int -> IO ()
guessGame n =
putStrLn "Guess the number (1-10): " >>= \_ ->
getLine >>= \input ->
Nothing    -> putStrLn "not sure what you just typed!" >>= \_ ->
guessGame n
Just guess ->
if guess == n
then putStrLn "You guessed it!"
else putStrLn "Wrong!" >>= \_ ->
guessGame n

main :: IO ()
main = randomIO (1,10) >>= guessGame
```

### 11.3 Do notation

Haskell provides a nicer notation of composing IO actions with `do` notation

```import Text.Read
import System.Random

guessGame :: Int -> IO ()
guessGame n = do
putStrLn "Guess the number (1-10): "
input <- getLine
Nothing -> do putStrLn "not sure what you just typed!"
guessGame n
Just guess ->
if guess == n
then putStrLn "You guessed it!"
else do putStrLn "Wrong!"
guessGame n

main :: IO ()
main = do
n <- randomRIO (1,10)
guessGame n
```

### 11.4 Looping

We can loop with the monadic map `mapM_`

```                         ┌-<-<-<-<-<-<-<-┐
|               |
v               |

map  M  _ :: (a -> IO ()) -> [a] -> IO ()

^  ^    ^^^^^^^^^^^^    ^^^    ^^^^^
|  |        |            |       |
|  |            to run   |
works on Monads ┘  |                     |
|                     └-- list to run it on

^^^^^^^^^^^^^^^^^^^^^
naming convention
```

For example, to print the ASCII value of `Char` from A to Z

```main = mapM_ (print . fromEnum) ['A'..'Z']
```

where

```print    :: Show a => a -> IO ()
fromEnum :: Enum a => a -> Int
```

This type of looping is more limited than `for (;;)` from C-like languages - you cannot `break` out of it for one. Instead of having a few general control structures, Haskell has many specialized ones, and the ability to easily write your own.

### 11.5 Concurrent IO

Haskell comes with light concurrency primitives. So light in fact that it might be better to use one of the abstractions built on top of them, like the `async` package:

```async :: IO a   ->   IO (Async a)

^^^^        ^^^^^^^^^^^^
|               |
computation to run       v
|
v
|
┌--<-<-<-<-<--┘
v
|
v
|
vvvvvvv

wait  :: Async a   ->   IO a

^^^^
|
result of computation
```

For example we can spawn ten threads that do some work, wait for the results and then print them.

```import Control.Concurrent
import Control.Concurrent.Async

main = do
let worker n = do
return (n * 2)

ts <- mapM (async . worker) [1..10]

results <- mapM wait ts

mapM_ print results
```

Note that `return` is a function with type `a -> IO a`. It has no flow control meaning like in many languages. It's simply turning the `Int` into an `IO Int`.

## 12 More

Created: 2014-05-01 Thu 15:47

Emacs 24.3.1 (Org mode 8.2.4)

Validate