haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 why study...

76
Haskell Yu Zhang Acknowledgement: modified from Stanford CS242 https://courseware.stanford.edu/pg/courses/317431/ Course web site: http://staff.ustc.edu.cn/~yuzhang/fpl Spring 2013

Upload: others

Post on 29-Jun-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

HaskellYu Zhang

Acknowledgement: modified from Stanford CS242 https://courseware.stanford.edu/pg/courses/317431/

Course web site: http://staff.ustc.edu.cn/~yuzhang/fpl

Spring 2013

Page 2: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

2

Reading

“Concepts in Programming Languages”Chapter 5https://courseware.stanford.edu/mod/file/download.php?file_guid=96710

“Real World Haskell”http://book.realworldhaskell.org/ https://rwh.readthedocs.org

Others● http://haskell.org/ghc/docs/latest/html/libraries/● Books&tutorials: http://haskell.org/haskellwiki/Books_and_tutorials● Research papers: http://haskell.org/haskellwiki/Research_papers ● Bloggers: http://haskell.org/haskellwiki/Blog_articles

Page 3: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

3

Language Evolution

Algol 60

Algol 68

ML Modula

Lisp

Pascal

Haskell

C

C++

Smalltalk

Java

Many others: Algol 58, Algol W, Fortran, Ada, Perl, Python, Ruby, C#, Javascript, F#...

Page 4: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

4

C Programming Language

● Dennis Ritchie, ACM Turing Award for Unix● Statically typed, general purpose systems programming

language● Computational model reflects underlying machine● Relationship between arrays and pointers

– An array is treated as a pointer to first element– E1[E2] is equivalent to ptr dereference: *((E1)+(E2))– Pointer arithmetic is not common in other languages

● Not statically type safe– If variable has type float, no guarantee value is floating pt

● Ritchie quote– “C is quirky, flawed, and a tremendous success”

Page 5: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

5

ML programming language● Statically typed, general-purpose programming language

– “Meta-Language” of the LCF theorem proving system● Type safe, with formal semantics● Compiled language, but intended for interactive use● Combination of Lisp and Algol-like features

– Expression-oriented– Higher-order functions– Garbage collection– Abstract data types– Module system– Exceptions

● Used in printed textbook as example language

Robin Milner, ACM Turing-Award for ML, LCF Theorem Prover, ...

Page 6: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

6

Haskell

● Haskell programming language is– Similar to ML: general-purpose, strongly typed, higher-order,

functional, supports type inference, interactive and compiled use– Different from ML: lazy evaluation, purely functional

core, rapidly evolving type system● Designed by committee in 80’s and 90’s to unify

research efforts in lazy languages– Haskell 1.0 in 1990, Haskell ‘98, Haskell’ ongoing– “A History of Haskell: Being Lazy with Class” HOPL 3

Paul Hudak

John Hughes

SimonPeyton Jones

Philip Wadler

Page 7: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

7

Haskell B Curry

● Combinatory logic– Influenced by Russell and Whitehead– Developed combinators to represent

substitution– Alternate form of lambda calculus that

has been used in implementation structures

● Type inference– Devised by Curry and Feys– Extended by Hindley, Milner

Although “Currying” and “Curried functions” are named after Curry, the idea was invented by Schoenfinkel earlier

Page 8: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

8

Why Study Haskell?

● Good vehicle for studying language concepts● Types and type checking

– General issues in static and dynamic typing– Type inference– Parametric polymorphism– Ad hoc polymorphism (aka, overloading)

● Control– Lazy vs. eager evaluation– Tail recursion and continuations– Precise management of effects

Page 9: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

9

Why Study Haskell?

● Functional programming will make you thinkdifferently about programming.– Mainstream languages are all about state– Functional programming is all about values

● Haskell is “cutting edge”– A lot of current research is done using Haskell– Rise of multi-core, parallel programming likely to make

minimizing state much more important● New ideas can help make you a better

programmer, in any language

Page 10: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

10

Most Research Languages

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000

The quick death

Geeks

Pra

ctit

ioners

Page 11: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

11

Successful Research Languages

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000

The slow death

Geeks

Pra

ctit

ion

ers

Page 12: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

12

C++, Java, Perl, Ruby

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000 The complete absence of death

Geeks

Pra

ctit

ioners Threshold of immortality

Page 13: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

13

Haskell

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000

The second life?

Geeks

Pra

ctit

ioners

“Learning Haskell is a great way of training yourself to think

functionally so you are ready to take full advantage of C# 3.0

when it comes out” (blog Apr 2007)

“I'm already looking at coding problems and my

mental perspective is now shifting back and forth between purely OO and

more FP styled solutions” (blog Mar 2007)

Page 14: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

14

Haskell Implementation

● The Haskell Platform for Windows, Mac OS, Linux– First get and install Glasgow Haskell Compiler 7.4.2

http://www.haskell.org/ghc/ ./configure && sudo make install

– Install OpenGL utility toolkitsudo apt-get install freeglut3 freeglut3-dev

– Install the Haskell Platform 2012.4.0.0http://www.haskell.org/platform

./configure && make && sudo make install– Interactive

ghci or ghci intro.hs– Compiled

ghc -make intro.hs ./intro

Page 15: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

15

Function Types in Haskell

● In Haskell, f :: A → B means for every x ∈ A,

f(x) = some element y = f(x) ∈ B

run forever

In words, “if f(x) terminates, then f(x) ∈ B.”

● In ML, functions with type A → B can throw an exception or have other effects, but not in Haskell

Page 16: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

16

Higher-Order Functions● Functions that take other functions as arguments or return

as a result are higher-order functions.● Common Examples:

– Map: applies argument function to each element in a collection.– Reduce: takes a collection, an initial value, and a function, and

combines the elements in the collection according to the function.

● Google uses Map/Reduce to parallelize and distribute massive data processing tasks. (Dean & Ghemawat, OSDI 2004)

Page 17: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

17

Basic Overview of Haskell

● Interactive Interpreter (ghci): read-eval-print– ghci infers type before compiling or executing

Type system does not allow casts or other loopholes!● Examples

Prelude> :set +t // print type after evaluationPrelude>(5+3)-26it :: IntegerPrelude> if 5>3 then “Harry” else “Hermione”“Harry”it :: [Char] -- String is equivalent to [Char]Prelude> 5==4Falseit :: Bool

● Prelude>:set +m // allow multiline commands● Prelude>:help

Page 18: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

18

Overview by Type

● BooleansTrue, False :: Boolif ... then ... else … --types must match

● Integers0, 1, 2, ... :: Integer+, * , ...:: Integer-> Integer -> Integer

● Strings“Ron Weasley” :: [Char]

● String is a synonym for the type [Char]● Floats

1.0, 2.0, 3.14159, …:: Double

http://haskell.org/ghc/docs/latest/html/libraries/

Page 19: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

19

Simple Compound Types

● Tuples(4, 5, “Griffendor”) :: (Integer, Integer, String)

● Lists[ ] :: [a] -- polymorphic type1 : [2, 3, 4] :: [Integer] -- infix cons notation

● Recordsdata Person = Person {firstName :: String, lastName :: String}

deriving (Eq, Ord, Show, Read)let hg = Person { firstName = “Hermione”, lastName = “Granger”}hg::Person

Page 20: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

20

Patterns and Declarations

● Patterns can be used in place of variables<pat> ::= <var> | <tuple> | <cons> | <record> ...

● Value declarations– General form: <pat> = <exp>

let <pat> = <exp> // in ghci● ghci only accepts a highly restricted subset of Haskell

– ExamplesmyTuple = (“Flitwick”, “Snape”)(x,y) = myTuplemyList = [1, 2, 3, 4]z:zs = myList

– Local declarationslet (x,y) = (2, “Snape”) in x * 4

In ghci, you need input:● Prelude> let myTuple = …● Prelude> let (x,y) = …

Or you can save the left code into a file, e.g. ex.hs, then in ghci, you can input:● Prelude> :load ex.hs● Prelude>myTuple

Page 21: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

21

Functions and Pattern Matching● Anonymous function

\x -> x+1 --like Lisp lambda, function (...) in JS● Function declaration form

<fname> <pat1> = <exp1>...<fname> <patn> = <expn> // default form in the slides

– In ghci,let { <fname> <pat> = <exp>;...; <fname> <pat> = <exp>}

● Examplesf (x,y) = x+y --argument must match pattern (x,y)length [ ] = 0length (x:s) = 1 + length(s)f :: Num a => (a, a) → a length :: Num a => [t] → a

Page 22: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

22

Map Function on Lists

● Apply function to every element of listmap f [ ] = [ ]map f (x:xs) = f x : map f xs

– map :: (t → a) → [t] → [a]map (\x -> x+1) [1,2,3] // [2,3,4]

● Compare to Lisp(define map (lambda (f xs) (if (eq? xs ()) () (cons (f (car xs)) ((map f (cdr xs))))))

Page 23: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

24

More Efficient Reverse

reverse xs = let rev ( [ ], accum ) = accum rev ( y:ys, accum ) = rev ( ys, y:accum ) in rev ( xs, [ ] )

1

2

3 1

2

3 1

2

3 1

2

3

Page 24: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

25

List Comprehensions

● Notation for constructing new lists from old:myData = [1,2,3,4,5,6,7]twiceData = [2 * x | x <- myData] -- [2,4,6,8,10,12,14]twiceEvenData = [2 * x| x <- myData, x `mod` 2 == 0]

-- [4,8,12]● Similar to “set comprehension”

{ x | x ∈ Odd ∧ x > 6 }

Page 25: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

26

Datatype Declarations

● Examplesdata Color = Red | Yellow | Blue

● elements are Red, Yellow, Blue

data Atom = Atom String | Number Int● elements are Atom “A”, Atom “B”, ..., Number 0, ...

data List = Nil | Cons (Atom, List)● elements are Nil, Cons(Atom “A”, Nil), ...● Cons(Number 2, Cons(Atom(“Bill”), Nil)), ...

● General formdata <name> = <clause> | ... | <clause><clause> ::= <constructor> | <contructor> <type>

● Type name and constructors must be Capitalized.

Page 26: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

27

Datatypes and Pattern Matching

● Recursively defined data structuredata Tree = Leaf Int | Node (Int, Tree, Tree) deriving (Eq, Show, Read)Node(4, Node(3, Leaf 1, Leaf 2), Node(5, Leaf 6, Leaf 7))

● Recursive functionsum::Tree → Int sum (Leaf n) = nsum (Node(n,t1,t2)) = n + sum(t1) + sum(t2)

4

5

76

3

21

Page 27: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

28

Example: Evaluating Expressions

● Define datatype of expressionsdata Exp = Var Int | Const Int | Plus (Exp, Exp)

● write (x+3)+ y as Plus(Plus(Var 1, Const 3), Var 2)● Evaluation function

ev :: Exp → Expev(Var n) = Var nev(Const n ) = Const nev(Plus(e1,e2)) = …

● Examplesev(Plus(Const 3, Const 2)) // Const 5ev(Plus(Var 1, Plus(Const 2, Const 3))) // Plus(Var 1, Const 5)

Page 28: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

29

Case Expression

● Datatypedata Exp = Var Int | Const Int | Plus (Exp, Exp)

● Case expressioncase e of Var n -> ... Const n -> ... Plus(e1,e2) -> …

● Indentation matters in case statements in Haskell.

In ghci,

case e of {

Var n -> … ;

Const n -> … ;

Plus(e1,e2) -> … }

Page 29: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

30

Evaluation by Cases

data Exp = Var Int | Const Int | Plus (Exp, Exp)let { ev ( Var n) = Var n; ev ( Const n ) = Const n; ev ( Plus ( e1,e2 ) ) = case ev e1 of { Var n -> Plus( Var n, ev e2) ; Const n -> case ev e2 of { Var m -> Plus( Const n, Var m); Const m -> Const (n+m); Plus(e3,e4) -> Plus ( Const n, Plus ( e3, e4 )) }; Plus(e3, e4) -> Plus( Plus ( e3, e4 ), ev e2) }}

Page 30: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

31

Laziness

● Haskell is a lazy language● Functions and data constructors don’t evaluate

their arguments until they need themcond :: Bool -> a -> a -> acond True t e = tcond False t e = e

● Programmers can write control-flow operators that have to be built-in in eager languages

(||) :: Bool -> Bool -> Bool -- short-circuiting “or”True || x = TrueFalse || x = x

Page 31: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

32

Lazy Evaluation

● An examplemagic :: Int -> Int -> [Int]magic 0 _ = [ ]magic m n = m : (magic n (m+n))getIt :: [Int] -> Int -> IntgetIt [ ] _ = 0getIt (x:xs) 1 = xgetIt (x:xs) n = getIt xs (n-1)

– getIt ( magic 1 1) 3● (magic 1 1) is just the fibonacci

numbers● the evaluation of (magic 1 1) never

terminates, but the evaluation of thisexpression in fact does

getIt ( magic 1 1 ) 3

=> getIt ( 1: (magic 1 (1+1)) ) 3

=> getIt ( magic 1 (1+1) ) (3-1)

=> getIt ( 1:(magic (1+1) (1+(1+1))))

(3-1)

=> getIt ( 1:(magic (1+1) (1+(1+1))))

2

=> getIt (magic (1+1) (1+(1+1)))

(2-1)

=> getIt ( magic 2 (1+(1+1))) (2-1)

=> getIt ( 2:(magic (1+(1+1))

(2+(1+(1+1)))) (2-1)

=> getIt ( 2:(magic (1+(1+1))

(2+(1+(1+1)))) 1

=> 2

Page 32: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

33

Core Haskell

● Basic Types– Unit– Booleans– Integers– Strings– Reals– Tuples– Lists– Records

● Patterns● Declarations● Functions● Polymorphism● Type declarations● Type Classes● Monads● Exceptions

Page 33: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

34

Testing

● It’s good to write tests as you write code● E.g. reverse undoes itself, etc.

reverse xs = let rev ( [ ], z ) = z rev ( y:ys, z ) = rev( ys, y:z ) in rev( xs, [ ] )--Write properties in Haskelltype TS = [Int]-- Test at this typeprop_RevRev :: TS -> Boolprop_RevRev ls = reverse (reverse ls) == ls

Page 34: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

35

Test Interactively

Prelude> :m +Test.QuickCheckPrelude Test.QuickCheck>quickCheck prop_RevRev

● Test.QuickCheck is simply a Haskell library (not a “tool”)

Prelude Test.QuickCheck>:t quickCheckquickCheck :: Testable prop => prop -> IO ()

● IO: indicates that the function is impure (has side effects)

http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck

Page 35: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

36

Things to Notice

● No side effects at all.reverse :: [a] → [a]

● A call to reverse returns a new list; the old one is unaffected.

prop_RevRev ls = reverse (reverse ls) == ls● A variable ls stands for an immutable value, not for

a location whose value can change● Laziness forces this purity

– Lazy evaluation makes it hard to reason about– Side effects in a lazy language would be extremely

unintuitive.

Page 36: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

37

Things to Notice

● Purity makes the interface explicit.reverse :: [a] → [a] -- Haskell

– Takes a list, and returns a list; that's all.

void reverse ( list l ) /* C */– Takes a list, may modify it; may modify other persistent

state; may do I/O.

Page 37: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

38

Things to Notice

Pure functions are easy to test.prop_RevRev ls = reverse (reverse ls) == ls

● In an imperative or OO language, you have to– set up the state of the object and the external state it

reads or writes– make the call– inspect the state of the object and the external state– perhaps copy part of the object or global state, so that

you can use it in the postcondition

Page 38: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

39

Things to Notice

Types are everywhere.reverse :: [a] → [a]

● Usual static-typing panegyric omitted...● In Haskell, types express high-level design, in the

same way that UML diagrams do, with the advantage that the type signatures are machine-checked.

● Types are (almost always) optional: type inference fills them in if you leave them out.

Page 39: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

HaskellYu Zhang

Acknowledgement: modified from Stanford CS242 https://courseware.stanford.edu/pg/courses/317431/

Course web site: http://staff.ustc.edu.cn/~yuzhang/fpl

Spring 2013

Page 40: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

2

Reading

“Concepts in Programming Languages”Chapter 5https://courseware.stanford.edu/mod/file/download.php?file_guid=96710

“Real World Haskell”http://book.realworldhaskell.org/ https://rwh.readthedocs.org

Others● http://haskell.org/ghc/docs/latest/html/libraries/● Books&tutorials: http://haskell.org/haskellwiki/Books_and_tutorials● Research papers: http://haskell.org/haskellwiki/Research_papers ● Bloggers: http://haskell.org/haskellwiki/Blog_articles

AJAX 指异步 JavaScript 及 XML ( Asynchronous JavaScript And XML )。 AJAX 是一种在 2005 年由 Google 推广开来的编程模式。

Page 41: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

3

Language Evolution

Algol 60

Algol 68

ML Modula

Lisp

Pascal

Haskell

C

C++

Smalltalk

Java

Many others: Algol 58, Algol W, Fortran, Ada, Perl, Python, Ruby, C#, Javascript, F#...

Page 42: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

4

C Programming Language

● Dennis Ritchie, ACM Turing Award for Unix● Statically typed, general purpose systems programming

language● Computational model reflects underlying machine● Relationship between arrays and pointers

– An array is treated as a pointer to first element– E1[E2] is equivalent to ptr dereference: *((E1)+(E2))– Pointer arithmetic is not common in other languages

● Not statically type safe– If variable has type float, no guarantee value is floating pt

● Ritchie quote– “C is quirky, flawed, and a tremendous success”

Page 43: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

5

ML programming language● Statically typed, general-purpose programming language

– “Meta-Language” of the LCF theorem proving system● Type safe, with formal semantics● Compiled language, but intended for interactive use● Combination of Lisp and Algol-like features

– Expression-oriented– Higher-order functions– Garbage collection– Abstract data types– Module system– Exceptions

● Used in printed textbook as example language

Robin Milner, ACM Turing-Award for ML, LCF Theorem Prover, ...

● LCF : Logic for Computable Functions

Page 44: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

6

Haskell

● Haskell programming language is– Similar to ML: general-purpose, strongly typed, higher-order,

functional, supports type inference, interactive and compiled use– Different from ML: lazy evaluation, purely functional

core, rapidly evolving type system● Designed by committee in 80’s and 90’s to unify

research efforts in lazy languages– Haskell 1.0 in 1990, Haskell ‘98, Haskell’ ongoing– “A History of Haskell: Being Lazy with Class” HOPL 3

Paul Hudak

John Hughes

SimonPeyton Jones

Philip Wadler

Hudak, Paul; Hughes, John; Peyton Jones, Simon; Wadler, Philip (2007). "A History of Haskell: Being Lazy with Class". Proceedings of the third ACM SIGPLAN conference on History of programming languages (HOPL III): 12-1–55.

Page 45: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

7

Haskell B Curry

● Combinatory logic– Influenced by Russell and Whitehead– Developed combinators to represent

substitution– Alternate form of lambda calculus that

has been used in implementation structures

● Type inference– Devised by Curry and Feys– Extended by Hindley, Milner

Although “Currying” and “Curried functions” are named after Curry, the idea was invented by Schoenfinkel earlier

Page 46: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

8

Why Study Haskell?

● Good vehicle for studying language concepts● Types and type checking

– General issues in static and dynamic typing– Type inference– Parametric polymorphism– Ad hoc polymorphism (aka, overloading)

● Control– Lazy vs. eager evaluation– Tail recursion and continuations– Precise management of effects

Page 47: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

9

Why Study Haskell?

● Functional programming will make you thinkdifferently about programming.– Mainstream languages are all about state– Functional programming is all about values

● Haskell is “cutting edge”– A lot of current research is done using Haskell– Rise of multi-core, parallel programming likely to make

minimizing state much more important● New ideas can help make you a better

programmer, in any language

cutting edge :最前沿

Page 48: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

10

Most Research Languages

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000

The quick death

Geeks

Pra

ctit

ioners

Page 49: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

11

Successful Research Languages

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000

The slow death

Geeks

Pra

ctit

ioners

Page 50: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

12

C++, Java, Perl, Ruby

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000 The complete absence of death

Geeks

Pra

ctit

ioners Threshold of immortality

Page 51: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

13

Haskell

1yr 5yr 10yr 15yr

1,000,000

1

100

10,000

The second life?

Geeks

Pra

ctit

ioners

“Learning Haskell is a great way of training yourself to think

functionally so you are ready to take full advantage of C# 3.0

when it comes out” (blog Apr 2007)

“I'm already looking at coding problems and my

mental perspective is now shifting back and forth between purely OO and

more FP styled solutions” (blog Mar 2007)

Page 52: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

14

Haskell Implementation

● The Haskell Platform for Windows, Mac OS, Linux– First get and install Glasgow Haskell Compiler 7.4.2

http://www.haskell.org/ghc/ ./configure && sudo make install

– Install OpenGL utility toolkitsudo apt-get install freeglut3 freeglut3-dev

– Install the Haskell Platform 2012.4.0.0http://www.haskell.org/platform

./configure && make && sudo make install– Interactive

ghci or ghci intro.hs– Compiled

ghc -make intro.hs ./intro

Page 53: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

15

Function Types in Haskell

● In Haskell, f :: A → B means for every x ∈ A,

f(x) = some element y = f(x) ∈ B

run forever

In words, “if f(x) terminates, then f(x) ∈ B.”

● In ML, functions with type A → B can throw an exception or have other effects, but not in Haskell

Page 54: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

16

Higher-Order Functions● Functions that take other functions as arguments or return

as a result are higher-order functions.● Common Examples:

– Map: applies argument function to each element in a collection.– Reduce: takes a collection, an initial value, and a function, and

combines the elements in the collection according to the function.

● Google uses Map/Reduce to parallelize and distribute massive data processing tasks. (Dean & Ghemawat, OSDI 2004)

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

foldl, applied to a binary operator, a starting value (typically the left-identity of the operator), and a list, reduces the list using the binary operator, from left to right

Page 55: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

17

Basic Overview of Haskell

● Interactive Interpreter (ghci): read-eval-print– ghci infers type before compiling or executing

Type system does not allow casts or other loopholes!● Examples

Prelude> :set +t // print type after evaluationPrelude>(5+3)-26it :: IntegerPrelude> if 5>3 then “Harry” else “Hermione”“Harry”it :: [Char] -- String is equivalent to [Char]Prelude> 5==4Falseit :: Bool

● Prelude>:set +m // allow multiline commands● Prelude>:help

Page 56: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

18

Overview by Type

● BooleansTrue, False :: Boolif ... then ... else … --types must match

● Integers0, 1, 2, ... :: Integer+, * , ...:: Integer-> Integer -> Integer

● Strings“Ron Weasley” :: [Char]

● String is a synonym for the type [Char]● Floats

1.0, 2.0, 3.14159, …:: Double

http://haskell.org/ghc/docs/latest/html/libraries/

Page 57: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

19

Simple Compound Types

● Tuples(4, 5, “Griffendor”) :: (Integer, Integer, String)

● Lists[ ] :: [a] -- polymorphic type1 : [2, 3, 4] :: [Integer] -- infix cons notation

● Recordsdata Person = Person {firstName :: String, lastName :: String}

deriving (Eq, Ord, Show, Read)let hg = Person { firstName = “Hermione”, lastName = “Granger”}hg::Person

Page 58: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

20

Patterns and Declarations

● Patterns can be used in place of variables<pat> ::= <var> | <tuple> | <cons> | <record> ...

● Value declarations– General form: <pat> = <exp>

let <pat> = <exp> // in ghci● ghci only accepts a highly restricted subset of Haskell

– ExamplesmyTuple = (“Flitwick”, “Snape”)(x,y) = myTuplemyList = [1, 2, 3, 4]z:zs = myList

– Local declarationslet (x,y) = (2, “Snape”) in x * 4

In ghci, you need input:● Prelude> let myTuple = …● Prelude> let (x,y) = …

Or you can save the left code into a file, e.g. ex.hs, then in ghci, you can input:● Prelude> :load ex.hs● Prelude>myTuple

Page 59: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

21

Functions and Pattern Matching● Anonymous function

\x -> x+1 --like Lisp lambda, function (...) in JS● Function declaration form

<fname> <pat1> = <exp1>...<fname> <patn> = <expn> // default form in the slides

– In ghci,let { <fname> <pat> = <exp>;...; <fname> <pat> = <exp>}

● Examplesf (x,y) = x+y --argument must match pattern (x,y)length [ ] = 0length (x:s) = 1 + length(s)f :: Num a => (a, a) → a length :: Num a => [t] → a

Page 60: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

22

Map Function on Lists

● Apply function to every element of listmap f [ ] = [ ]map f (x:xs) = f x : map f xs

– map :: (t → a) → [t] → [a]map (\x -> x+1) [1,2,3] // [2,3,4]

● Compare to Lisp(define map (lambda (f xs) (if (eq? xs ()) () (cons (f (car xs)) ((map f (cdr xs))))))

Page 61: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

24

More Efficient Reverse

reverse xs = let rev ( [ ], accum ) = accum rev ( y:ys, accum ) = rev ( ys, y:accum ) in rev ( xs, [ ] )

1

2

3 1

2

3 1

2

3 1

2

3

Page 62: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

25

List Comprehensions

● Notation for constructing new lists from old:myData = [1,2,3,4,5,6,7]twiceData = [2 * x | x <- myData] -- [2,4,6,8,10,12,14]twiceEvenData = [2 * x| x <- myData, x `mod` 2 == 0]

-- [4,8,12]● Similar to “set comprehension”

{ x | x ∈ Odd ∧ x > 6 }

Page 63: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

26

Datatype Declarations

● Examplesdata Color = Red | Yellow | Blue

● elements are Red, Yellow, Blue

data Atom = Atom String | Number Int● elements are Atom “A”, Atom “B”, ..., Number 0, ...

data List = Nil | Cons (Atom, List)● elements are Nil, Cons(Atom “A”, Nil), ...● Cons(Number 2, Cons(Atom(“Bill”), Nil)), ...

● General formdata <name> = <clause> | ... | <clause><clause> ::= <constructor> | <contructor> <type>

● Type name and constructors must be Capitalized.

Page 64: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

27

Datatypes and Pattern Matching

● Recursively defined data structuredata Tree = Leaf Int | Node (Int, Tree, Tree) deriving (Eq, Show, Read)Node(4, Node(3, Leaf 1, Leaf 2), Node(5, Leaf 6, Leaf 7))

● Recursive functionsum::Tree → Int sum (Leaf n) = nsum (Node(n,t1,t2)) = n + sum(t1) + sum(t2)

4

5

76

3

21

Page 65: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

28

Example: Evaluating Expressions

● Define datatype of expressionsdata Exp = Var Int | Const Int | Plus (Exp, Exp)

● write (x+3)+ y as Plus(Plus(Var 1, Const 3), Var 2)● Evaluation function

ev :: Exp → Expev(Var n) = Var nev(Const n ) = Const nev(Plus(e1,e2)) = …

● Examplesev(Plus(Const 3, Const 2)) // Const 5ev(Plus(Var 1, Plus(Const 2, Const 3))) // Plus(Var 1, Const 5)

Page 66: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

29

Case Expression

● Datatypedata Exp = Var Int | Const Int | Plus (Exp, Exp)

● Case expressioncase e of Var n -> ... Const n -> ... Plus(e1,e2) -> …

● Indentation matters in case statements in Haskell.

In ghci,

case e of {

Var n -> … ;

Const n -> … ;

Plus(e1,e2) -> … }

Page 67: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

30

Evaluation by Cases

data Exp = Var Int | Const Int | Plus (Exp, Exp)let { ev ( Var n) = Var n; ev ( Const n ) = Const n; ev ( Plus ( e1,e2 ) ) = case ev e1 of { Var n -> Plus( Var n, ev e2) ; Const n -> case ev e2 of { Var m -> Plus( Const n, Var m); Const m -> Const (n+m); Plus(e3,e4) -> Plus ( Const n, Plus ( e3, e4 )) }; Plus(e3, e4) -> Plus( Plus ( e3, e4 ), ev e2) }}

Page 68: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

31

Laziness

● Haskell is a lazy language● Functions and data constructors don’t evaluate

their arguments until they need themcond :: Bool -> a -> a -> acond True t e = tcond False t e = e

● Programmers can write control-flow operators that have to be built-in in eager languages

(||) :: Bool -> Bool -> Bool -- short-circuiting “or”True || x = TrueFalse || x = x

Page 69: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

32

Lazy Evaluation

● An examplemagic :: Int -> Int -> [Int]magic 0 _ = [ ]magic m n = m : (magic n (m+n))getIt :: [Int] -> Int -> IntgetIt [ ] _ = 0getIt (x:xs) 1 = xgetIt (x:xs) n = getIt xs (n-1)

– getIt ( magic 1 1) 3● (magic 1 1) is just the fibonacci

numbers● the evaluation of (magic 1 1) never

terminates, but the evaluation of thisexpression in fact does

getIt ( magic 1 1 ) 3

=> getIt ( 1: (magic 1 (1+1)) ) 3

=> getIt ( magic 1 (1+1) ) (3-1)

=> getIt ( 1:(magic (1+1) (1+(1+1))))

(3-1)

=> getIt ( 1:(magic (1+1) (1+(1+1))))

2

=> getIt (magic (1+1) (1+(1+1)))

(2-1)

=> getIt ( magic 2 (1+(1+1))) (2-1)

=> getIt ( 2:(magic (1+(1+1))

(2+(1+(1+1)))) (2-1)

=> getIt ( 2:(magic (1+(1+1))

(2+(1+(1+1)))) 1

=> 2

Page 70: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

33

Core Haskell

● Basic Types– Unit– Booleans– Integers– Strings– Reals– Tuples– Lists– Records

● Patterns● Declarations● Functions● Polymorphism● Type declarations● Type Classes● Monads● Exceptions

Page 71: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

34

Testing

● It’s good to write tests as you write code● E.g. reverse undoes itself, etc.

reverse xs = let rev ( [ ], z ) = z rev ( y:ys, z ) = rev( ys, y:z ) in rev( xs, [ ] )--Write properties in Haskelltype TS = [Int]-- Test at this typeprop_RevRev :: TS -> Boolprop_RevRev ls = reverse (reverse ls) == ls

Page 72: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

35

Test Interactively

Prelude> :m +Test.QuickCheckPrelude Test.QuickCheck>quickCheck prop_RevRev

● Test.QuickCheck is simply a Haskell library (not a “tool”)

Prelude Test.QuickCheck>:t quickCheckquickCheck :: Testable prop => prop -> IO ()

● IO: indicates that the function is impure (has side effects)

http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck

Page 73: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

36

Things to Notice

● No side effects at all.reverse :: [a] → [a]

● A call to reverse returns a new list; the old one is unaffected.

prop_RevRev ls = reverse (reverse ls) == ls● A variable ls stands for an immutable value, not for

a location whose value can change● Laziness forces this purity

– Lazy evaluation makes it hard to reason about– Side effects in a lazy language would be extremely

unintuitive.

lazy evaluation makes it hard to reason about when things will be evaluated; hence including side effects in a lazy language would be extremely unintuitive. Historically, this is the reason Haskell is pure: initially, the designers of Haskell wanted to make a lazy functional language, and quickly realized it would be impossible unless it also disallowed side effects.

http://www.cis.upenn.edu/~cis194/lectures/2012-02-16.html

Page 74: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

37

Things to Notice

● Purity makes the interface explicit.reverse :: [a] → [a] -- Haskell

– Takes a list, and returns a list; that's all.

void reverse ( list l ) /* C */– Takes a list, may modify it; may modify other persistent

state; may do I/O.

Page 75: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

38

Things to Notice

Pure functions are easy to test.prop_RevRev ls = reverse (reverse ls) == ls

● In an imperative or OO language, you have to– set up the state of the object and the external state it

reads or writes– make the call– inspect the state of the object and the external state– perhaps copy part of the object or global state, so that

you can use it in the postcondition

Page 76: Haskellstaff.ustc.edu.cn/~yuzhang/fopl/2013s/lectures/haskell.pdf · 2013-02-27 · 9 Why Study Haskell? Functional programming will make you think differently about programming

39

Things to Notice

Types are everywhere.reverse :: [a] → [a]

● Usual static-typing panegyric omitted...● In Haskell, types express high-level design, in the

same way that UML diagrams do, with the advantage that the type signatures are machine-checked.

● Types are (almost always) optional: type inference fills them in if you leave them out.