Haskell and Haskell VV What is Haskell Haskell

  • Slides: 28
Download presentation
Haskell and Haskell. VV

Haskell and Haskell. VV

What is Haskell? • “Haskell is a polymorphically typed, lazy, pure functional language. ”

What is Haskell? • “Haskell is a polymorphically typed, lazy, pure functional language. ” – www. haskell. org • So what does this mean?

Haskell is…a functional language Imperative (C, C++) Functional (Lisp, ML) • Program is a

Haskell is…a functional language Imperative (C, C++) Functional (Lisp, ML) • Program is a single sequence of steps function evaluation • Subroutines are called • Sub-expressions are in a specific order evaluated when needed • How to calculate • What is calculated

…a pure functional language • No side effects!

…a pure functional language • No side effects!

Types in Haskell • num = 2 num : : Int • inc x

Types in Haskell • num = 2 num : : Int • inc x = 1 + x inc : : Int → Int • add x y = x + y add : : Int → Int • Could be Int → Int or • could be Int → (Int → Int) • a function returning a function!

Types in Haskell • (add 1) : : Int → Int • (add 1)

Types in Haskell • (add 1) : : Int → Int • (add 1) x = 1 + x • inc = add 1 “currying”

Other types • Bool, Char • [] are lists – [Bool] or [Char] (String

Other types • Bool, Char • [] are lists – [Bool] or [Char] (String = [Char]) • (, ) (, , ) and so on are pairs, triples, n-tuples – (Bool , Int) or (Bool , [Char] , Int) • [(Bool , [Char → Int] , [[(Char, Bool)]])]

…is a functional language (2) • Functions are first-order objects! • Functions can be

…is a functional language (2) • Functions are first-order objects! • Functions can be passed as arguments: – sort : : [Int] → [Int] – sort. By : : (Int → Bool) → [Int] – sort. By (<) – sort. By (>) – sort. By (custom. Ordering)

…is polymorphically typed • sort. By : : (a → Bool) → [a] •

…is polymorphically typed • sort. By : : (a → Bool) → [a] • a can be any type: – sort. By : : (Int → Bool) → [Int] – sort. By : : (Char→Bool) → String →String – sort. By : : ((Int , Int) → Bool) → [(Int , Int)] • sort. By (<) : : [a] → [a] (more or less)

Example: quicksort qsort : : [a] → [a] qsort [] = [] qsort (x:

Example: quicksort qsort : : [a] → [a] qsort [] = [] qsort (x: xs) = (qsort lt) ++ [x] ++ (qsort gt) where lt = filter (<x) xs gt = filter (>x) xs We could also write qsort. By, replacing (<x) with (f x)

Haskell is lazy • eg. head (qsort list) – Only the first element is

Haskell is lazy • eg. head (qsort list) – Only the first element is needed, so the lists gt are never computed! • qsort (x: xs) = (qsort lt) ++ … • = (qsort (l: ls) ++ … … • = ((…(qsort [] ++ [y] ++ …)… • qsort (x: xs) = y

One more important function • map : : (a → b) → [a] →

One more important function • map : : (a → b) → [a] → [b] • Applies a function f to every element in a list (or, more generally, any data structure) • eg. map (*2) [1, 2, 3] = [2, 4, 6]

Haskell. VV • mesh, vtx. Label, vtx. Data ← polymorphic • No global state

Haskell. VV • mesh, vtx. Label, vtx. Data ← polymorphic • No global state → labels particular to mesh • Query functions like – prev. To : : mesh → vtx. Label – lookup. Data : : mesh → vtx. Label → vtx. Data • Update functions like – set. NB : : mesh → vtx. Label → [vtx. Label] → mesh – lookup. Data : : mesh → (vtx. Label → vtx. Data) → mesh

Haskell. VV • Long operations are clumsy insert. Vertex m p q x =

Haskell. VV • Long operations are clumsy insert. Vertex m p q x = replace. With ( set. NB m x [p, q] ) p q x) q p x)

Haskell. VV • There are ways around this: insert. Vertex m p q x

Haskell. VV • There are ways around this: insert. Vertex m p q x = let m 1 = set. NB m x [p, q] in let m 2 = replace. With m 1 p q x in let m 3 = replace. With m 2 q p x in … • The problem remains: we want sequential operations.

Monads • Mathematical structures offering operations which satisfy certain rules … • Imperative operations

Monads • Mathematical structures offering operations which satisfy certain rules … • Imperative operations are monads!

Monads • provide a way to incorporate ‘side effects’ • eg. I/O operations –

Monads • provide a way to incorporate ‘side effects’ • eg. I/O operations – put. Str : : String → IO () – get. Str : : IO String • (get. Str >>= str → put. Str str) : : IO () • (do { str ← get. Str; put. Str str; }) : : IO ()

Monads • This looks like imperative code, but… 1. Side-effects are precisely controlled 2.

Monads • This looks like imperative code, but… 1. Side-effects are precisely controlled 2. These are first-order objects! – map put. Str [“one” , ”two” , ”three” , …] • is actually a list of I/O operations – [IO ()] , ([IO String] , Bool → IO ()) – sequence [do {str ← get. Str; put. Str str; } , (put. Str “foo”) , …]

Monads and Haskell. VV • use a monad Mesh. Op: prev. To. Op :

Monads and Haskell. VV • use a monad Mesh. Op: prev. To. Op : : vtx. Label→Mesh. Op vtx. Label set. NBOp : : vtx. Label → [vtx. Label] → Mesh. Op () • Mesh. Op is just an operation: • execute. Mesh. Op : : Mesh. Op () → mesh

Example: insert. Vertex : : vtx. Label → Mesh. Op vtx. Label insert. Vertex

Example: insert. Vertex : : vtx. Label → Mesh. Op vtx. Label insert. Vertex p q = do lbl ← new. Vertex. Op set. NBOp lbl [p, q] replace. With. Op p q lbl replace. With. Op q p lbl return lbl

Monads and Haskell. VV • Some things are easy (like forall): map some. Operation

Monads and Haskell. VV • Some things are easy (like forall): map some. Operation (list. Vertices mesh) map insert. Vertex (list. Neighbours mesh) • However, many vv programs require two (or more) passes through a forall statement • Hmmm…maybe Haskell can help here?

Delay monads • The Delay monad lets you arbitrarily delay an operation: synchronize (

Delay monads • The Delay monad lets you arbitrarily delay an operation: synchronize ( do { delay a; b; }) ↔ do { b; a; } • A vertex or pair can be dealt with in one go: synchronize (map do. Something (get. Vertices mesh))

Example: delayed. Insert. Vertex : : vtx. Label → Mesh. Op vtx. Label d.

Example: delayed. Insert. Vertex : : vtx. Label → Mesh. Op vtx. Label d. Insert. Vertex p q = do lbl ← new. Vertex. Op delay (do set. NBOp lbl [p, q] replace. With. Op p q lbl replace. With. Op q p lbl) return lbl

Example, continued • An operation can then be some. Operation = synchronize ( map

Example, continued • An operation can then be some. Operation = synchronize ( map handle. One (get. Neighbours mesh)) where handle. One (p, q) = do lbl ← delay. Insert. Vertex p q some. Other. Operation p q • some. Other. Operation uses all of the old neighbourhoods!

Conclusion • What’s good about Haskell (and Haskell. VV? ) – Delayed operations –

Conclusion • What’s good about Haskell (and Haskell. VV? ) – Delayed operations – Strict semantics (no side-effects) – Easier to understand the code – Operations are implementation independent – Haskell code can be as fast as C / C++ – Windowing support, Open. GL libraries, …

Conclusion • What’s bad about Haskell (and Haskell. VV? ) – Haskell is functional

Conclusion • What’s bad about Haskell (and Haskell. VV? ) – Haskell is functional and lazy • Expressions are stored until evaluated (or garbage collected) • If you’re not careful, the heap can fill up with unevaluated expressions – Current implementation of vv is slow

What have I left out? • Type classes – define what functions may be

What have I left out? • Type classes – define what functions may be applied to a type – for instance, (<) : : a → Bool is only defined for a in class Ord: • (<) : : (Ord a) => a → Bool – Haskell. VV defines classes • • Mesh mesh vtx. Label vtx. Data Mesh. Op op mesh vtx. Label vtx. Data Vector. Space field vector and others

More information • http: //www. haskell. org – Haskell homepage, lots of information, plus

More information • http: //www. haskell. org – Haskell homepage, lots of information, plus compilers, interpreters, etc. • http: //www. cpsc. ucalgary. ca/~laneb/Haskell. VV – Adding my code, will archive this presentation, etc.