Introduction to Functional Programming Using Haskell

Download Report

Transcript Introduction to Functional Programming Using Haskell

Using Haskell
Dan Vasicek
2010 – 02 – 21
What is Haskell? (Theoretical Aspects)
• Haskell is a computer programming language
• In particular, it is a polymorphically statically
typed, lazy, purely functional language, quite
different from most other programming
languages
• The language is named for Haskell Brooks Curry,
whose work in mathematical logic serves as a
foundation for functional languages
• Haskell is based on the lambda calculus, hence
the symbol, λ, is used as part of the Haskell logo
What is Haskell? (Practical Aspects)
• Two commands for your command line environment
• ghc – Glasgow Haskell Compiler: produces executable
code from Haskell source
• ghci – Glasgow Haskell Command line Interpreter:
– An environment for the execution of Haskell commands
– Special commands for manipulating, & querying the
environment
– Debugging commands
– Foreign language (e.g. C++) interface
Why Consider Haskell?
•
•
•
•
•
Produces concise, provably correct code
Short code development time
Interactive and compilable
Built-in Concurrency and Parallelism
A high level modern programming language that
is a result of 20 years of development
• Supported by a large library of packaged modules
• Supplied with debuggers and profilers
• Freely available (Open source, $0, complete
development package)
Installation of Glasgow Haskell Platform
• Download most recent version
– Stable versions from:
http://hackage.haskell.org/platform
• Windows version is 54 Megabytes (Feb 1, 2010)
• Mac OS X is 106 Megabytes
• Source tarball is 1.28 Megabytes
– Linux X86 & X86-64 ~ 72 Megabytes
• http://haskell.org/ghc/download_ghc_6_10_4.html#x86linux
• Other Haskell Compilers - e.g.
http://repetae.net/computer/jhc/ (Efficient)
Example GHCi Session - Strings
Glasgow Haskell Platform
• GHC 6.10.4 - The state-of-the-art optimzing compiler for Haskell.
• GHCi 6.10.4 - A bytecode interpreter and interactive environment for
Haskell
• The GHCi debugger - An interactive, imperative-style debugger for Haskell
• The GHC parallel runtime - a multicore language runtime, featuring
lightweight threads, thread sparks, affinity control, and a parallel garbage
collector
• The Happy parser generator - Happy 1.18.4, a yacc-like parser generator for
Haskell
• The Alex lexer generator - Alex 2.3.1, a lex-like lexer generator for Haskell
• The Haddock Documentation tool - generator Haddock 2.4.2
• The Cabal package distribution tool - cabal-install 0.6.2, download and
install new Haskell packages from Hackage
• The hsc2hs foreign language binding tool - a preprocessor for binding
Haskell to C - (e.g. Access to HDF5, FITS, … data)
• Unicode built-in
Editor Syntax highlighting and
formatting support
• Emacs Haskell Mode
• VIM “Superior Haskell Interaction Mode”
(SHIM)
List of Available Packages
• http://hackage.haskell.org/packages/hackage.html
• Currently there are 1800 Haskell Packages
available
• Compare to 9033 Python packages available
• See the appendix of these slides for a listing of
some Haskell Packages
Haskell Syntax – Some References
• http://www.haskell.org/onlinereport/syntaxiso.html - general syntax description
• http://www.haskell.org/onlinereport/standard
-prelude.html - standard functions
• http://www.cs.chalmers.se/Cs/Grundutb/Kurs
er/d1pt/d1pta/ListDoc - Standard list
functions
Simple Syntax
•
•
•
•
•
Strongly Typed
Simple arithmetic
Arbitrary precision integers
String manipulation
List manipulation such as sorting
Positionally Sensitive Notation
• The next character following any of the keywords
where, let, or of is what determines the starting
column for the declarations in the where, let, or case
expression being written
• Be sure that the starting column is further to the right
than the starting column associated with the
immediately surrounding clause (otherwise it would be
ambiguous). The "termination" of a declaration
happens when something appears at or to the left of
the starting column associated with that binding form.
(Haskell observes the convention that tabs count as 8
blanks; thus care must be taken when using an editor
which may observe some other convention.)
Type Signatures (::)
•
•
•
•
•
•
5 :: Integer
'a' :: Char
”abc” :: [Char] (is a list of characters)
(+1) :: Integer -> Integer {e.g. (+1) 1 =2)}
[1,2,3] :: [Integer] - List of Integers
('b',4) :: (Char,Integer) - Pair
Simple Arithmetic Using GHCi
•
•
•
•
•
•
Prelude> 3+7
10
Prelude> 2*8
16
Prelude> 100/25
4.0
Arbitrary Precision Integers in GHCi
• Prelude> 2^200
•
1606938044258990275541962092341162602522202993782792835301376
•
•
•
•
•
61 digits (Same result as Mathematica)
Prelude> 1/3
0.3333333333333333
Sixteen significant figures
log(10^300)/log(10) = 299.9999999999994
List Operations
•
•
•
•
•
•
•
•
•
•
•
“abc” is [‘a’, ‘b’, ‘c’]
“abc”!!0 is ‘a’
“abc”!!2 is ‘c’
“ab” ++ “cd” is “abcd”
head “abc” is ‘a’
tail “abc” is “bc”
take 2 “abc” is “ab”
take 1 “abc” is “a” is [‘a’]
drop 1 “abc” is “bc”
reverse(“abcdefg”) is “gfedcba”
length(“abc”) is 3
list item
Concatination
car
cdr
Shorthand for lists of integers
• [1..4]  [1,2,3,4]
• [1,3..10]  [1,3,5,7,9]
• [1,3..]  [1,3,5,7,9,11, … infinite sequence
More List Operations
•
•
•
•
•
•
•
•
map (/2) [1, 2, 3] is [.5, 1.0, 1.5]
map sin [1, 2, 3] is [.84, .91, .14]
foldr (+) 0 [1, 2, 3, 4] is 10
(Σn=1n=4n)
foldr (*) 0 [1..4] is 0
foldr (*) 1 [1,2,3,4] is 24
(4!)
filter (4<) [1, 2, 8, 7] is [8,7]
partition (<5) [1..8] returns
([1,2,3,4],[5,6,7,8])
Define a simple function
•
•
•
•
•
•
let sq(x) = x*x
sq(9)
81
sq 5
25
sq is a function that is no more special than *
or + (more on the next slide)
Redefine basic operations
• let x + y = x*y
• Then 4+5=20
Type and definition of “map”
using patterns
• map
map f []
map f (x:xs)
:: (a->b) -> [a] -> [b]
= []
= f x : map f xs
• map f
:: [a]  [b]
GHCi Commands
•
•
•
•
•
•
•
•
The “:” operator tells GHCi to expect a command
:? Or : Gives a summary of : commands
:browse – will list the current environment
:browse <module name> – will list the contents of a
module
:show – will display the syntax of the show command
:show bindings – will display current bindings
:! Cmd – pass Cmd to the shell
E.g. :!dir – will display the current directory (in DOS)
Example of the “:show” command
• :show bindings
• sq :: (Num a) = > aa = _
• Which says that sq is a function of numbers
that takes a number, returns a number, and
prints the value of the number
Creating a Haskell Script
• :set editor "C:\Program Files\Vim\vim72\gvim.exe“
– Sets the editor to be gvim
• :edit fac.hs
• Creates a file called fac.hs containing
– fac(0) = 1
– fac(n) = n*fac(n-1)
• :load fac
• Compiles and loads fac.hs into the
environment
Executing “fac” script
•
•
•
•
•
fac(3)
6
fac(10)
2628800
The function “fac” is called “primitive
recursive”
Validation of “fac”
•
•
•
•
•
by induction
fac(0)=1
fac(1) =1
fac(2)=2
Fac(100) is a big number and is probably
correct
Ackermann’s Function
• Is not primitive recursive
• Definition -----------------------------------------– ack(0,n)
= n+1
– ack(m+1, 0) = ack(m,1)
– ack(m,n) = ack(m-1,ack(m,n-1))
• Program Validation----------------------------– ack(0,0) = 1 √
– ack(2,0)= 5 √
– ack(3,3) = 61 √
Inquire about the environment
• :show modules
• Main ( fac.hs, interpreted)
GHCi Configuration
• When GHCi starts it executes config files in
order:
1. .ghci file
2. appdata/ghc/ghci.conf where appdata is
• C:/Documents and Settings/user/Application Data (on
MS Win)
• $HOME/.ghc/ghci.conf (on Unix)
3. $HOME/ghci.conf
Creating a GHCi configuration file
• :edit .ghci
• Type a configuration script for example:
– :set editor "C:\Program Files\Vim\vim72\gvim.exe“
• Save this file in the default GHCi directory
– To find the default directory see the results of the
• :!dir command on windows
• :!pwd on Linux
• Now gvim will be the default editor instead of
Notepad
Begin Functional Programming
Segment
•
Fundamental concepts
–
–
–
–
–
–
–
•
Simple data types
–
–
–
•
Numbers
Lists
Trees
Efficiency
–
–
–
•
•
•
•
•
Functional Programming
Sessions and scripts
Polymorphic types
Order of evaluation
Patterns
Lazy evaluation
Side Effects
Evaluation order
Lazy Evaluation
Space
Abstract Data Types
Infinite lists
Monads
Parsing
Examples
Functional Programming
• A functional program is a function that solves
a problem
• That function may involve several subsidiary
functions and is described in a notation that
obeys normal mathematical principles
• The result of the function is the solution of the
problem and is disjoint from the input to the
function
Fundamental Concepts
• Polymorphic Static types
– length(list) – The list can have elements of any type.
So, length is polymorphic. It can be applied to lists of
characters, numbers, tuples, lists, …
– length []
=0
– length (x:xs) = 1+ length xs
• Where [] is a pattern that means the empty list
• And x:xs is a pattern that means x is the first element of the
input list and xs is the rest of the list
– Pattern matching is an important component of
Haskell
Polymorphism
• head
• head (x:xs)
:: [a] -> a
= x
tail
:: [a] -> [a]
tail (x:xs)
= xs
• Both fail if presented with an empty list
• Both work for lists of anything, even lists of
empty lists and are Polymorphic
• Examples of the Hindley-Milner type system
Order of Evaluation
• Order of evaluation (simplification, or reduction)
is not specified in a functional program
• sq(3+4) could be simplified as
– sq(7) 7*7  49
– (3+4)*(3+4) 7*(3+4) 7*749
• Both orders produce the same result
• The independence of the result from the order is
a characteristic feature functional programs
Lazy Evaluation
• Let three x = 3
• Let infinity = infinity +1
• Now simplify the expression
– three infinity
– If we choose to simplify infinity first we get
• Three(infinity +1 +1 +1 and so on)
• which does not terminate
– If we choose to simplify three first,
• three infinity = 3
• the expression terminates in one step
• Some simplification orders may terminate while others do
not
• In GHCi three infinity =3
Lazy Evaluation
• Guarantees termination whenever
termination is possible
Side Effects
•
•
•
•
A pure function simply returns a value
A pure function has no internal state
A pure function cannot modify the input data
In GHCi values may be displayed by the
interactive environment
• Monadic programming allows functional
programs to mimic imperative programs
• Monads provide a way to execute “Commands”
and display values
Basic Data Types
•
•
•
•
Bool
Char
Enumerations
Tuples
Unicode in Haskell
• Haskell 98 specification says that Haskell
supports Unicode
• http://blog.kfish.org/2007/10/survey-haskellunicode-support.html
• http://code.haskell.org/utf8-string/
Unicode table
Unicode Experiment
• Create a list of byte codes for some Hebrew characters:
• hebrew = ['\n', '\x05d0', '\x05d1', '\x05d2', '\x05d3',
'\x05d4', '\x05d5', '\x05d6', '\x05d7', '\x05d8',
'\x05d9','\x5da','\x5db','\x5dc','\x5de','\x5df', '\x05e0',
'\x0e1', '\x05e2', '\x05e3', '\x05e4', '\x05e5', '\x05e6',
'\x05e7', '\x05e8', '\x05e9' , '\x05ea', '\x05eb', '\x05ec',
'\x05ed', '\x05ee', '\x05ef' , '\n','\n‘]
• putStr hebrew
• Result on next slide
Result of “putStr hebrew”
Unicode Greek
The letters printed by my program are in the order
αβ Γ Π Σ σμτΦΘΩδ
And this does not agree with the order in the
above table.
Encoding Problem
• Hexadecimal ‘\x05d0’ = ‘\1488’ decimal
• So, my coding is not the problem
Quick Sort Algorithm
•
•
•
•
•
qsort [] = []
qsort ( x:xs) = qsort (filter (<= x) xs) ++
qsort (filter ( > x) xs)
Inefficient! Calls filter twice for xs
Can use (length (x:xs))2memory
Begin Appendix
• Details of available modules
• Comparison to other languages
• List of some Haskell functions
List of Packages
• http://hackage.haskell.org/packages/archive/
pkg-list.html
Example: Algorithm package
• binary-search library: Binary and exponential searches
• Binpack library: Common bin-packing heuristics.
• DecisionTree library: A very simple implementation of decision
trees for discrete attributes.
• Diff library: O(ND) diff algorithm in haskell.
• dom-lt library: The Lengauer-Tarjan graph dominators algorithm.
• edit-distance library and programs: Levenshtein and restricted
Damerau-Levenshtein edit distances
• funsat library and program: A modern DPLL-style SAT solver
• garsia-wachs library: A Functional Implementation of the GarsiaWachs Algorithm
• Graphalyze library: Graph-Theoretic Analysis library.
• GraphSCC library: Tarjan's algorithm for computing the strongly
connected components of a graph.
Default Packages – provided by the
downloaded system (283
functions)
• ghc-prim
• integer - Arbitrary Precision Integer Arithmetic
• base – basic data types and functions
–31 data types
• rts
More Algorithms
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
hgal library: library for computation automorphism group and canonical labelling of a graph
hmm library: Hidden Markov Model algorithms
incremental-sat-solver library: Simple, Incremental SAT Solving as a Library
infinite-search library: Exhaustively searchable infinite sets.
iproute library: IP Routing Table
kmeans library: K-means clustering algorithm
ListTree library: Combinatoric search using ListT
markov-chain library: Markov Chains for generating random sequences with a user definable behaviour.
Munkres library: Munkres' assignment algorithm (hungarian method)
natural-sort library: User-friendly text collation
Numbers library: An assortment of number theoretic functions
NumberSieves library: Number Theoretic Sieves: primes, factorization, and Euler's Totient
palindromes library and program: Finding palindromes in strings
pqueue-mtl library: Fully encapsulated monad transformers with queuelike functionality.
presburger library: Cooper's decision procedure for Presburger arithmetic.
primes library: Efficient, purely functional generation of prime numbers
queuelike library: A library of queuelike data structures, both functional and stateful.
rangemin library: Linear range-min algorithms.
sat programs: CNF SATisfier
sat-micro-hs program: A minimal SAT solver
satchmo library: SAT encoding monad
satchmo-examples programs: examples that show how to use satchmo
satchmo-funsat library: funsat driver as backend for satchmo
teams library: Graphical modeling tools for sequential teams
TrieMap library: Automatic type inference of generalized tries.
union-find library: Efficient union and equivalence testing of sets.
Modules in the Default Package
array
bytestring
Cabal
containers
directory
editline
filepath
haskell98
hpc
old-locale
old- time
packedstring
pretty
process
random
readline
syb
template-haskell
unix
Win32
Some Haskell Functions
(From the appendix of the book)
• (.) – Functional Composition
• (.) :: (β  γ)  (αβ)  (αγ)
• (f.g)x =f(g x)
•
•
•
•
(++) Concatenation of two lists
(++)
:: [α]  [α]  [α]
[] ++ ys
= ys
(x:xs) ++ ys = x: (xs ++ ys)
More Functions
•
•
•
•
(^) Conjunction
(^)
:: Bool  Bool  Bool
True ^ x = x
False ^ x = False
•
•
•
•
(v) Disjunction
(v)
:: Bool  Bool  Bool
True v x = True
False v x = x
More Functions
•
•
•
•
•
(!!) List indexing
(!!) :: [a]  Int a
[]!!n = error “(!!): Index too large”
(x:xs)!!0 = x
(x:xs)!!(n+1) = xs!!n
• and returns the conjunction of a list of booleans
• and :: [Bool]  Bool
• and = foldr (^) True
More Functions
• concat Concatineates a list of lists
• concat :: [[a]] [a]
• concat = foldr (++) []
• const creates a constant valued function
• const :: a  b a
• const (x,y) = x
More Functions
• cross Applies a pair of functions to the
corresponding elements of a pair
• cross
:: (a b, c d)  (a,c)  (b,d)
• cross (f,g) = pair(f.fst, g.snd)
• curry converts a non-curried function into a
curried one
• curry
:: ((a,b)c) (abc)
• curry f x y = f(x,y)
List Functions documented at:
• http://www.cs.chalmers.se/Cs/Grundutb/Kurs
er/d1pt/d1pta/ListDoc/
Comparison to other languages
•
•
•
•
•
•
•
Haskell separates the definition of a type from the definition of the methods associated with that
type. A class in C++ or Java usually defines both a data structure (the member variables) and the
functions associated with the structure (the methods). In Haskell, these definitions are separated.
The class methods defined by a Haskell class correspond to virtual functions in a C++ class. Each
instance of a class provides its own definition for each method; class defaults correspond to default
definitions for a virtual function in the base class.
Haskell classes are roughly similar to a Java interface. Like an interface declaration, a Haskell class
declaration defines a protocol for using an object rather than defining an object itself.
Haskell does not support the C++ overloading style in which functions with different types share a
common name.
The type of a Haskell object cannot be implicitly coerced; there is no universal base class such as
Object which values can be projected into or out of.
C++ and Java attach identifying information (such as a VTable) to the runtime representation of an
object. In Haskell, such information is attached logically instead of physically to values, through the
type system.
There is no access control (such as public or private class constituents) built into the Haskell class
system. Instead, the module system must be used to hide or reveal components of a class.