Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Fancy Types
Rich Libraries
Practical Tools
::
HASKELL
Pure Functional Programming
February 12, 2014
Levi Pearson
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
FUNCTIONAL PROGRAMMING?
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
FUNCTIONAL DIFFERENCES
No side effects
Order of evaluation is less significant
Equational reasoning
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
FUNCTIONAL POWER
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
AN OBLIGATORY EXAMPLE
10
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
LAZY EVALUATION
11
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
fibs = ...
fib 4
Substitute the definition of fib:
fib = (fibs !!)
Giving:
fibs = ...
fibs !! 4
12
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
fibs = ...
fibs !! 4
The !! operator is just a function:
fibs = ...
(!!) fibs 4
In a strict (applicative order) language, we would fully evaluate
fibs now and fall into infinite recursion. In Haskell, we evaluate
(!!) instead!
13
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
14
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
= 1
= ...
= 4
xs 3
15
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
= 1
= ...
= 3
xs 2
16
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
= 1
= zipWith (+) fibs (tail fibs)
= 3
xs 2
17
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
18
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
= (1 + 1)
= zipWith (+) as bs
= 2
xs 1
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
=
=
=
=
=
(+)
1
(1 + 1) : ...
(1 + 1)
...
1) : zipWith (+) as bs
22
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
= (1 + (1 + 1))
= zipWith (+) as bs
= 1
xs 0
23
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
= (+)
= (1 + (1 + 1)) : ...
= ...
+ (1 + (1 + 1)) : zipWith (+) as bs
24
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
25
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
26
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
ADVANTAGES OF LAZINESS
http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
http://www.amazon.com/Purely-Functional-Structures-ChrisOkasaki/dp/0521663504
http://okasaki.blogspot.com/2008/02/ten-years-of-purelyfunctional-data.html
27
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
COSTS OF LAZINESS
28
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
29
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Fancy Types
30
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
ALGEBRAIC DATA
Lists are supported with special syntax, but you can build an
equivalent type with a data declaration:
data List a = Cons a (List a)
| Nil
This means: For all types a, we can form a List a value by
supplying the constructor Cons with a value of type a and another
value of type List a, or by using the constructor Nil.
-- Equivalent to [1, 2, 3] or 1 : 2 : 3 : []
sugarFreeList = Cons 1 (Cons 2 (Cons 3 Nil))
31
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
33
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
34
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
34
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
34
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
PARAMETRICITY
In Haskell type signatures, type variables are implicitly
universally quantified.
35
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
PARAMETRICITY
In Haskell type signatures, type variables are implicitly
universally quantified.
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
PARAMETRIC REASONING
Parametricity places restrictions on a (pure, total) function's
behavior that can provide powerful tools for reasoning.
f :: (a -> Bool) -> [a] -> [a]
36
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
PARAMETRIC REASONING
Parametricity places restrictions on a (pure, total) function's
behavior that can provide powerful tools for reasoning.
f :: (a -> Bool) -> [a] -> [a]
f takes a function a to Bool and a list of a, then returns a list of a
36
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
PARAMETRIC REASONING
Parametricity places restrictions on a (pure, total) function's
behavior that can provide powerful tools for reasoning.
f :: (a -> Bool) -> [a] -> [a]
f takes a function a to Bool and a list of a, then returns a list of a
The output list's elements may only come from the input list
Which elements from the input, which order, and how many
of each may only vary based on the predicate and the input
The decision may only inspect the length of the input list and
apply the predicate to its elements
36
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
TYPE CLASSES
What type should we give the following function?
(+) :: ? -> ? -> ?
37
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
TYPE CLASSES
What type should we give the following function?
(+) :: ? -> ? -> ?
(+) :: Integer -> Integer -> Integer
This would require a different operator for Float addition. . . .
(+) :: a -> a -> a
This won't work due to parametricity.
37
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
TYPE CLASSES
What type should we give the following function?
(+) :: ? -> ? -> ?
(+) :: Integer -> Integer -> Integer
This would require a different operator for Float addition. . . .
(+) :: a -> a -> a
This won't work due to parametricity.
(+) :: Num a => a -> a -> a
Bounded polymorphism constrains parametricity with a predicate:
``For all types a for which Num a holds, take an a and another a and
return an a as the result.''
37
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
KINDS
For example:
Int :: *
a -> a :: *
[] :: * -> *
(->) :: * -> * -> *
40
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
CONSTRUCTOR CLASSES
The class constraint mechanism applies to more than ordinary
types
41
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Mapping the identify function over a list returns the same list:
map id [1, 2, 3] ==> [1, 2, 3]
42
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
43
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
SO WHAT?
44
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
45
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
AVOIDING AWKWARDNESS
We have two functions, f and g, that we would like to compose:
f :: b -> c
g :: a -> Maybe b
We can solve this problem by lifting f to the Maybe Functor:
(fmap f)
g
(fmap f) . g :: a
-> Maybe c
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Rich Libraries
47
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
PRELUDE
48
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
BASE
Standard libraries that ship with GHC, including Prelude.
http://hackage.haskell.org/package/base
49
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
CONTAINERS / UNORDERED-CONTAINERS
50
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
BYTESTRING / TEXT
The Prelude's String is defined as:
type String = [Char]
This is convenient, but not fast.
http://hackage.haskell.org/package/bytestring
51
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
NETWORK
52
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
53
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
BINARY
http://hackage.haskell.org/package/binary
54
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
STM
Composable Memory Transactions Tim Harris, Simon Marlow, Simon Peyton Jones, and Maurice
Herlihy (2005)
http://research.microsoft.com/Users/simonpj/papers/stm/index.htm
55
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
AESON
http://hackage.haskell.org/package/aeson
56
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
PIPES / CONDUIT
http://hackage.haskell.org/package/pipes
http://hackage.haskell.org/package/conduit
57
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
LENS
http://hackage.haskell.org/package/lens
https://github.com/ekmett/lens/wiki
http://skillsmatter.com/podcast/scala/lenses-compositionaldata-access-and-manipulation
58
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
Practical Tools
59
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
GHC
Compiler
Interactive interpreter
Integrated build system and library management
Highly optimizing, with user-definable rewrite rules
Standards-compliant by default, but supports many fancy
extensions
https://www.haskell.org/ghc/
60
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
CABAL
http://www.haskell.org/cabal/
61
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
HADDOCK
http://www.haskell.org/haddock/
62
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
HACKAGE
http://www.haskell.org/haddock/
63
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
CRITEREON
Helps you ensure you are measuring the evaluation that you
want to be measuring
Performs statistical analysis of results to help determine the
reliability of the numbers
Produces pretty HTML results, including graphs
http://hackage.haskell.org/package/criterion
64
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
TASTY
https://hackage.haskell.org/package/tasty
65
Preliminaries
Fancy Types
Rich Libraries
Practical Tools
QUICKCHECK / SMALLCHECK
https://hackage.haskell.org/package/quicktest
https://hackage.haskell.org/package/smallcheck
66