2014-08-22 22:50:57 +00:00
|
|
|
---
|
|
|
|
title: Week One Notes
|
|
|
|
toc: no
|
|
|
|
format: markdown
|
|
|
|
...
|
|
|
|
|
|
|
|
# Week One - Haskell Basics
|
|
|
|
|
|
|
|
## What Is Haskell?
|
|
|
|
|
|
|
|
* Created in late 1980s by academics
|
|
|
|
* Functional
|
|
|
|
* Pure
|
|
|
|
* Lazy
|
|
|
|
* Statically Typed
|
|
|
|
|
|
|
|
## Course Themes
|
|
|
|
|
|
|
|
* Types
|
|
|
|
* Abstraction
|
|
|
|
* Wholemeal Programming
|
|
|
|
|
|
|
|
## Literate Haskell
|
|
|
|
|
|
|
|
* Only lines preceded by '>' are code
|
|
|
|
* All other lines are comments
|
|
|
|
|
|
|
|
## Declarations of Variables
|
|
|
|
|
|
|
|
~~~ {.haskell}
|
|
|
|
x :: Int
|
|
|
|
x = 3
|
|
|
|
~~~
|
|
|
|
|
|
|
|
* Declares a variable `x` of type `Int`
|
|
|
|
* Defines the value of the variable `x` to be `3`
|
|
|
|
* `=` is *definition*, not *assignment*
|
|
|
|
* variables are just names for values
|
|
|
|
|
|
|
|
## Basic Types
|
|
|
|
|
|
|
|
* `Int` - Machine-sized integers
|
|
|
|
* `Integer` - Arbitrary-precision integers
|
|
|
|
* `Double` - Double-precision floating point
|
|
|
|
* `Bool` - Booleans
|
|
|
|
* `Char` - Unicode characters
|
|
|
|
* `String` - Lists of characters with special syntax
|
|
|
|
|
|
|
|
## GHCi
|
|
|
|
|
|
|
|
* A Haskell Read Eval Print Loop (REPL)
|
|
|
|
* `:load` - load a haskell file
|
|
|
|
* `:reload` - reload the file
|
|
|
|
* `:type` - return the type of an expression
|
|
|
|
* `:?` - give a list of commands
|
|
|
|
|
|
|
|
## Arithmetic
|
|
|
|
|
|
|
|
* Infix operators, `+`, `-`, `*`, `\`, `^`
|
|
|
|
* Negation needs parens: `(-3)`
|
|
|
|
* `div` for integer division
|
|
|
|
* `mod` for integer remainder
|
|
|
|
* Backticks turn named functions to infix operators
|
2014-08-24 06:54:17 +00:00
|
|
|
* Operands must have the same type - no implicit coercion
|
|
|
|
* `fromIntegral` converts from any integral type to any numeric type
|
|
|
|
* `round`, `floor`, `ceiling` convert from floating point numbers to
|
|
|
|
Int or Integer
|
2014-08-22 22:50:57 +00:00
|
|
|
|
|
|
|
## Boolean Logic
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* Type is `Boolean`
|
|
|
|
* Infix operators: `&&`, `||`
|
|
|
|
* `not` for negation
|
|
|
|
* Equality comparison: `==`, `/=`
|
|
|
|
* Order comparison: `<`, `>`, `<=`, `>=`
|
|
|
|
* Conditional: `if` *boolean* `then` *t_exp* `else` f_exp*
|
|
|
|
* Both *t_exp* and *f_exp* must have the same type
|
2014-08-22 22:50:57 +00:00
|
|
|
|
|
|
|
## Defining Basic Functions
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* Definition by cases
|
|
|
|
* `sumtorial :: Integer -> Integer` means "function from Integer to
|
|
|
|
Integer"
|
|
|
|
* Clauses are checked from top to bottom, first match chosen
|
|
|
|
* Values must be the same to match, variables match anything
|
|
|
|
* Choice by Boolean expression can be made by *guards*
|
|
|
|
* `otherwise` is a synonym for `True`
|
|
|
|
* Don't use conditional or guards to pick `True` or `False`; just
|
|
|
|
use the conditional directly
|
|
|
|
|
2014-08-22 22:50:57 +00:00
|
|
|
## Pairs
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* Syntax for type and value is `(` *x* `,` *y* `)`
|
|
|
|
* Types of *x* and *y* don't have to be the same
|
|
|
|
* Extract values via pattern-matching
|
|
|
|
* *n*-tuples for *n* > 2 also exist, but recommend against them
|
|
|
|
|
2014-08-22 22:50:57 +00:00
|
|
|
## Using Functions, Multiple Arguments
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* Application via juxtaposition of function with arguments.
|
|
|
|
* Multi-argument function types look like `Int -> Int -> Int -> Int`
|
|
|
|
* Reason for the arrows to be revealed later
|
|
|
|
* Function application is **higher precedence** than any infix
|
|
|
|
operators
|
|
|
|
|
2014-08-22 22:50:57 +00:00
|
|
|
## Lists
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* List types look like `nums :: [Integer]` which is a "list of Integers"
|
|
|
|
* List value syntax sugar: `[1,2,3]`
|
|
|
|
* Ranges: `[1..100]`; `[2,4..100]` enumerates only evens
|
|
|
|
* Type `String` means the same as `[Char]`
|
|
|
|
* Value `"hello"` means the same as `['h','e','l','l','o']`
|
|
|
|
|
2014-08-22 22:50:57 +00:00
|
|
|
## Constructing Lists
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* Empty list: `[]`
|
|
|
|
* *cons* operator: *x* `:` *xs* where *xs* is a list of values of
|
|
|
|
the same type as *x*, possibly the empty list.
|
|
|
|
* Value `[2,3,4]` is the same as `2 : 3 : 4 : []`
|
|
|
|
|
2014-08-22 22:50:57 +00:00
|
|
|
## Functions on Lists
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* Define by cases; one for empty list, the other for a cons operator
|
|
|
|
* The pattern `_` can be used in place of a variable when the value
|
|
|
|
won't be used.
|
|
|
|
|
2014-08-22 22:50:57 +00:00
|
|
|
## Combining Functions
|
|
|
|
|
2014-08-24 06:54:17 +00:00
|
|
|
* Build complex functions by combining simple ones
|
|
|
|
* Lazy evaluation means list elements are only calculated as needed
|
|
|
|
* Don't be afraid to write small functions that transform entire
|
|
|
|
structures and combine them; it's not as inefficient as it might
|
|
|
|
seem
|
|
|
|
|
2014-08-22 22:50:57 +00:00
|
|
|
## A Word About Error Messages
|
2014-08-24 06:54:17 +00:00
|
|
|
|
|
|
|
* **Don't fear error messages**
|
|
|
|
* How to interpret type match errors
|
|
|
|
|
|
|
|
# Homework Assignment
|
|
|
|
|
|
|
|
The first problem involves validating credit card numbers.
|
|
|
|
|
|
|
|
1. Find the digits of a number; write the functions:
|
|
|
|
|
|
|
|
~~~ {.haskell}
|
|
|
|
toDigits :: Integer -> [Integer]
|
|
|
|
toDigitsRev :: Integer -> [Integer]
|
|
|
|
~~~
|
|
|
|
|
|
|
|
2. Double every other digit *from the right*
|
|
|
|
|
|
|
|
~~~ {.haskell}
|
|
|
|
doubleEveryOther :: [Integer] -> [Integer]
|
|
|
|
~~~
|
|
|
|
|
|
|
|
3. Sum the digits
|
|
|
|
|
|
|
|
~~~ {.haskell}
|
|
|
|
sumDigits :: [Integer] -> Integer
|
|
|
|
~~~
|
|
|
|
|
|
|
|
4. The number is valid iff the remainder when the sum is divided by
|
|
|
|
10 is 0
|
|
|
|
|
|
|
|
~~~ {.haskell}
|
|
|
|
validate :: Integer -> Bool
|
|
|
|
~~~
|
|
|
|
|
|
|
|
The second problem is to solve the Towers of Hanoi puzzle.
|
|
|
|
|
|
|
|
~~~ {.haskell}
|
|
|
|
type Peg = String
|
|
|
|
type Move = (Peg, Peg)
|
|
|
|
hanoi :: Integer -> Peg -> Peg -> Peg -> [Move]
|
|
|
|
~~~
|