# Reference card

(Difference between revisions)

## 1 General Syntax

```  {- A multiline comment
which can continue for many lines
-}
```
```  -- a single line comment
```

### 1.2 Conditionals

#### 1.2.1 if

``` if conditional then truePart else falsePart
if a == 12 then 14 else 22
```

#### 1.2.2 case

``` case exp of
Pattern1  -> action1
Pattern2  -> action2
_         -> else_action
```
``` case x of
[]  -> 0
[x] -> 1
_   -> -1
```

#### 1.2.3 Function pattern matching

``` f [ ] = 0
f [x] = 1
f _   = -1
```

#### 1.2.4 Function conditionals (guards)

``` f x | x == []        = 1
| length x == 12 = 15
| otherwise      = -1
```

### 1.3 Saving work

#### 1.3.1 where

``` f x = i * i
where i = g x
```

#### 1.3.2 let in

``` f x = let i = g x
in i * i
```

### 1.4 Declaring types

#### 1.4.1 data

``` data List = Cons Int List
| Nil
deriving (Eq, Show, Ord)
```

#### 1.4.2 type (type synonymns)

``` type String = [Char]
type Name = TypeValue
```

#### 1.4.3 class

``` class Check a where
test :: a -> Bool
force :: a -> a
```

#### 1.4.4 instance

``` instance Show List where
show x = "No show"
```

### 1.5 Calling functions

#### 1.5.1 Named functions

``` myFunc :: Int -> Int -> Int
result = myFunc 1 2
result = 1 `myFunc` 2
result = (myFunc 1) 2
result = (`myFunc` 2) 1
```

#### 1.5.2 Operators (and sections)

``` (+) :: Int -> Int -> Int
result = 1 + 2
result = (+) 1 2
result = (1 +) 2
result = (+ 2) 1
```

#### 1.5.3 Useful functions

``` myFunc 1 2 == (flip myFunc) 2 1
(f . g) x == f (g x)
f (a+b) == f \$ a+b
```

#### 1.5.4 Lambda Expressions

``` myFunc = (\ a b -> a + b)
result = map (\x -> head x) xs
```

### 1.6 List Expressions

#### 1.6.1 ..

``` [1..] = [1,2,3,4,5,6...
[1..5] = [1,2,3,4,5]
[1,3..5] = [1,3,5]
```

#### 1.6.2 List Comprehensions

``` [ x*x | x <- [1..3] ] ==> [1,4,9]
[ (x, y) | x < - [1..3], y <- "ab"] ==>
[(1,'a'),(1,'b'),(2,'a'),(2,'b'),(3,'a'),(3,'b')]
[ (x,y) | x <- [1..4], even x, y <- "ab" ] ==>
[(2,'a'),(2,'b'),(4,'a'),(4,'b')]
map f xs ==> [ f x | x <- xs ]
filter p xs ==> [ x | x <- xs, p x ]
```

## 2 Hello World

main = putStrLn "Hello World"

## 3 Snippets

### 3.1 fst3 :: (a, b, c) -> a

``` snd3 :: (a, b, c) -> b
thd3 :: (a, b, c) -> c
```
``` fst3 (x,_,_) = x
snd3 (_,x,_) = x
thd3 (_,_,x) = x
```

### 3.2 ordPair :: Ord a => a -> a -> (a, a)

``` ordPair x y = if x < y then (x, y) else (y, x)
```

### 3.3 lenXX# :: [a] -> Bool

``` lenEq0 = null
lenNe0 = not . null
```
``` lenEq1 [x] = True
lenEq1  _  = False
```
``` lenGt1 [x] = False
lenGt1 [ ] = False
lenGt1  _  = True
```

### 3.4 sortUnique :: Ord a => [a] -> [a]

``` sortUnique []  = []
sortUnique [x] = [x]
sortUnique xs = mergeUnique (sortUnique a) (sortUnique b)
where (a,b) = split xs
```

### 3.5 split :: [a] -> ([a], [a])

``` split []  = ([], [])
split [a] = ([a], [])
split (a:b:xs) = (a:as, b:bs)
where (as,bs) = split xs
```

### 3.6 mergeUnique :: Ord a => [a] -> [a] -> [a]

Precondition:

``` isUnique(#1) && isUnique(#2)
```
``` mergeUnique a  [] = a
mergeUnique [] b  = b
mergeUnique (a:as) (b:bs) =
case compare a b of
EQ -> a: mergeUnique as bs
LT -> a: mergeUnique as (b:bs)
GT -> b: mergeUnique (a:as) bs
```
``` fix :: Eq a => (a -> a) -> a -> a
```
``` fix f x = if x == x' then x else fix f x'
where x' = f x
```

## 4 Command lines

### 4.1 For hmake

``` hmake Test
hmake -realclean Test
```

Where Test is the name of the executable you want to build, i.e. where Test.hs contains the main function.

### 4.2 For ghc --make

``` ghc --make MainModule.hs -o ModuleExec
ghc --make Module.hs
```

Where ModuleExec is the name of the output binary you want to make (if main is exported). Module.o will be output for Module.hs, if main is not exported.

### 4.3 Others

``` runhaskell Test.hs
```
``` echo main | ghci -v0 Test.hs
```

### 4.4 #! notation

You can also just make single Haskell main modules executable, using a combination of runhaskell and #! notation:

``` #!/usr/bin/env runhaskell
main = putStrLn "hello"
```

Save this to a .hs file and then make this file executable:

```  chmod +x Test.hs
```

You can now execute this as a normal `script' file:

``` \$ ./Test.hs
hello
```