1. Introduction
Sebastian Rettig
“Work on Haskell began in 1987 when aa committee of
“Work on Haskell began in 1987 when committee of
researchers got together to design aa kick-ass language.”([1])
researchers got together to design kick-ass language.” ([1])
2. Imperative Programming
● Variables (value placeholder)
– Value can change during program flow
● Modules, Classes, Functions, Procedures
● Control Flow Structures (IF THEN ELSE,
Loops (WHILE), Goto)
3. Functional Programming
● No Variables
● Functions only, eventually stored in
Modules
– Behavior do not change, once defined
– → Function called with same parameter
calculates always the same result
● Function definitions (Match Cases)
● Recursion (Memory)
4. Haskell Features
● Pure Functional Programming Language
● Lazy Evaluation
● Pattern Matching and Guards
● List Comprehension
● Type Polymorphism
5. Haskell Functions (1)
● function contains header and body
● header consists of type definition:
<funcname> :: <param> [ -> <param_n>] -> <result>
● body consists of pattern rules and calculation
<funcname> <paramalias_1> [<paramalias_n>] = {calc}
– more later...
● Example (2 params if type [Int] & Int, result Bool):
isHead :: [Int] -> Int -> Bool
isHead xs i = i==head xs
6. Haskell Functions (2)
● You want an Interface? No Problem
myMap :: (Float -> Int) -> [Int] -> [Int]
● first parameter of myMap is a function
● allows all functions, with Float parameter and result of
type Int
● interface also individual extendable
myMap :: (Float -> Bool -> Int) -> [Int] -> [Int]
● or include a sub-level interface
myMap :: ((Int -> Float) -> Bool -> Int) -> [Int] -> [Int]
7. Lazy Evaluation
● Function execution only if result is needed
● → Program = series of data-transformations
● Example: A(B(C(x)))
– If A needs result from B → call B
– If B needs result from C → call C
8. Pattern Matching (1)
● create matching rules:
fac 0 = 1
fac n = n * fac (n-1)
● use wildcards to ignore parameters in
pattern:
take 0 _ = []
take _ [] = []
take n (x:xs) = [x] ++ take (n-1) xs
9. Pattern Matching (2)
● use Guards to separate a matching case deeper:
myFilter _ [] = []
myFilter f (x:xs)
| f==x = x:myFilter g xs
| otherwise = myFilter f xs
where g = 2*f
– like an IF THEN ELSE
– Guard Condition evaluate to Bool (True/False)
● eventually define values with where-clause
myFilter 2 [1,2,3,4,5,6] results to [2,4]
10. List Comprehension (1)
● Example Quicksort:
quicksort [] = []
quicksort (x:xs) =
quicksort [y | y <- xs,y<x] ++ [x] ++ quicksort[y | y <- xs,y>=x]
– Who the f??k needs an array?
● Lists are dynamic, flexible & part of the
language definition = deeply integrated
– List expression (x:xs)
● x is head of list (value),
● xs is tail (list)
● also individual extendable (x:y:ys)
– List Generator: [<value> | <pipe>, <match> ]
11. List Comprehension (2)
void qsort(int a[], int lo, int hi)
Quicksort in C: ([2])
{
int h, l, p, t;
if (lo < hi) {
l = lo;
h = hi;
p = a[hi];
do {
while ((l < h) && (a[l] <= p))
l = l+1;
while ((h > l) && (a[h] >= p))
h = h-1;
if (l < h) {
t = a[l];
a[l] = a[h];
a[h] = t;
}
} while (l < h);
a[hi] = a[l];
a[l] = p;
qsort( a, lo, l-1 );
qsort( a, l+1, hi );
}
}
12. List Comprehension (3)
● Example: double entries in list
doubleList [] = []
doubleList (x:xs) = x:x:doubleList xs
● Multiplication of a list of values:
Hugs> product [1..5]
120
● or in a function:
fac n = product [1..n]
13. Type Polymorphism
● Statically typed, but Compiler can read type from
context (type inference)
● → no need to set type explicitly
● → makes function more generic for different
kinds of types (type polymorphism)
– Why should I use quicksort :: [Int] -> [Int]
– even if I also want to sort character?
Hugs>quicksort ['f','a','d','b']
"abdf"
14. Recursion (1)
● we have no loops → use Recursion:
myMap :: Int -> [Int] -> [Int]
myMap v [] = [] -- Recursion Anchor!
myMap v (x:xs) = [v*x] ++ myMap v xs
● Recursion Anchor contains the break rule
– endless loop = anchorless recursion
isTrue :: Bool Bool
isTrue b = b && isTrue b
15. Recursion (2)
● Recursion vs. Final Recursion:
countX :: Int -> [Int] -> Int ● Hugs> countX 3 [1,4,3,5,3]
countX x [] = 0 2
countX x (y:ys)
| x==y = 1 + countX x ys
| otherwise = countX x ys
countXFinal :: Int -> [Int] -> Int -> Int
countXFinal x [] accu = accu
countXFinal x (y:ys) accu
| x==y = countXFinal x ys accu+1
| otherwise = countXFinal x ys accu
● use accumulator to reduce stack usage
● Hugs> countXFinal 3 [1,4,3,5,3] 0
2
16. History
● Haskell 1.0 (1990) – 1.4
● Haskell 98 (1997)
– quasi standard language definition
– Foreign Function Interface included ([3])
● Haskell Prime (2006 = ~)
– Haskell 2010 (2009)
● first revision
● → now Control Flow Structures available
(Why? I am currently not sure.)
17. Where to start?
● for Beginner – Hugs (Haskell User's Gofer System):
– Successor of Gofer Interpreter (http://www.haskell.org/hugs/)
– Syntax closer to Miranda than to Haskell, but contains
Haskell98 language specification
– really smart & easy installation in Mac using brew
18. Where to start?
● for Developer - Haskell Platform – Batteries Included:
– Big “Toy” in big Package at
(http://hackage.haskell.org/platform/)
– Contains Glasgow Haskell Compiler (GHC)
● THE one and only :)
● contains the full 2010 standard
● can also generate .cpp from .hs
– Contains Interpreter (GHCi)
● also Bytecode Interpreter like Hugs, but 2010
Standard
19. Sources
[1] Haskell-Tutorial: Learn you a Haskell (http://learnyouahaskell.com/,
2012/03/15)
[2] Haskell Introduction: Quicksort in C (
http://www.haskell.org/haskellwiki/Introduction, 2012/03/15)
[3] The Haskell 98 Foreign Function Interface Addendum (
http://www.cse.unsw.edu.au/~chak/haskell/ffi/, 2012/03/15)