Haskell Introduction
Cons: Constructor
[1, 2, 3] !! 1: Take second element from list
- Infix, compared to most other list functions!
- Prefix function application has preference
- Convention: Name list arguments with suffix
s, e.g. xs
Types and Classes
- Every well-formed expression has a type
e :: t: expression e produces a value of t
- Types are automatically determined by type inference at compile time
- It will always determine the most general type (complete and total type inference)
- A list is a sequence of values of the same type
- type of a list is e.g.
[Bool] or [Char]
- Function types:
f :: t1 -> tResult
- Curried Functions: Functions which take "multiple" arguments, i.e. one argument at a time, e.g.
add' or map
- The arrow
-> associates to the right
- Polymorphic functions: Type contains one or more type variables (like generics)
- Type constraints
- e.g.
(+) :: Num a => a -> a -> a
Num a is a type constraint and can only occur once in a type
Basic Types
Int: Fixed-precision integer
Integer: arbitrary-precision integer
Type Classes
Num: Numeric Types
Eq: Equality types (e.g. for (==))
Ord: Ordered types (for comparison)
Defining Functions
Conditional Expression
abs n = if n >= 0 then n else -n
- Can be nested
- Must always have an
else branch (to be unambiguous)
- Guarded Equations (syntactic sugar):
| abs n
| n >= 0 = n
| otherwise = -n
|
Pattern Matching
- Define functions with patterns
_ is a wildcard
- Conditions are evaluated top-down
- Definition should be exhaustive
| True && True = True
_ && _ = False
|
List Patterns
: is the cons operator to concatenate two elements
- A list is defined as:
[1, 2, 3] is syntactic sugar for ´1: (2: (3: []))´
Lambda expressions
⁻ \ x -> x + x
- \ is
- is (*2).(+1) in "point-free" form
Operator Sections
- Infix operators can be written as a curied functions in
()
- Selections:
(1+) = is a "plus one" function
List Comprehension
[x^2 | x <- [1..5]]
x <- [1..5] is a generator that generates values for x
[(x, y) | x <- [1, 2, 3], y <- [4, 5]]
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
- Notice: the
y generator is used up first
- Think of later generators as deeper nested loops
- later generators can therefore depend on earlier ones
- Defining guards:
[x | x <- [1 .. 10], even x]
Zip function
- Map tWo lists to a list of pairs until one of the two lists ends
zip :: [a] -> [b] -> [(a, b)]
zip ['a', 'b', 'c'] [1, 2, 3, 4] - [('a',1),('b',2),('c',3)]
String comprehensions
- Strings are represented as char lists, so they can be used like lists
Recursive Functions
Higher Order Functions
- Function which accepts functions as arguments and/or returns a function
- e.g.
map f xs = [f x | x <- xs]
filter p xs = [x | x <- xs, p x]
- General reduce / fold pattern:
f (x : xs) = x (+) f xs where (+) is some operator
- folder pattern is defined with
foldr
- first argument: operator like
(+) above
- second argument: result for base case
[]
- e.g.
sum = foldr (+) 0
(.)-function: "of"
Data Types
Polymorphism
- Slide 30: This is parametric polymorphism
- Haskell uses type classes to achieve ad-hoc polymorphism
- Similar to interfaces in Java
- class declarations specify which functions the type must have, and the type of the functions
- class types can be extended:
class Eq a => Ord a where ... extends Eq
- Functor is similar to the Visitor-Pattern
- The compiler can automatically generate default implementations for polymorphism with
deriving
Interactive Programming
- We need a way to input data with a keyboard and show data on a screen (side effects)
- Side effects are integrated into the type system of Haskell
- Basic Type:
IO a: The type of actions that return a value of type a
- Intuition: Function takes "the world" and returns it (possibly changed) along with a value
IO () is a type that returns no value
getChar and putChar read and write characters from keyboard to screen
do composes sequential actions together
return returns a value in a do
- assignment with
x <- func