Professional Documents
Culture Documents
Microsoft Research
Haskell is a programming language that is
purely functional
lazy
higher order
strongly typed
general purpose
Functional programming will make you think
differently about programming
Mainstream languages are all about state
Functional programming is all about values
1,000,000
10,000
100
Geeks
1,000,000
10,000
100
The slow death
Geeks
1,000,000
10,000
The complete
100 absence of death
Geeks
100
The second life?
Geeks
X11 Window
manager
Window
placement
Demo xmonad
Configuration Layout
data algorithm
Events
(mouse, kbd,
client)
X11 FFI State machine
Window
placement
Session state
Export A ring of windows
list One has the focus
Comments
Stack should not exploit the fact that it‟s a stack of windows
No import
any more A stack of values of
type Stack w = ...
type w
insert :: w -> Stack w
-- Newly inserted window has focus
insert = ...
swap [] = [] [a,b,c]
swap [w] = [w] means
swap (w1:w2:ws) = w2:w1:ws a:b:c:[]
swap ws = case ws of
[] -> []
[w] -> [w]
(w1:w2:ws) -> w2:w1:ws
case
expressions
Download:
ghc: http://haskell.org/ghc
Hugs: http://haskell.org/hugs
Interactive:
ghci Stack.hs
hugs Stack.hs
Compiled:
ghc –c Stack.hs
Demo ghci
A ring of windows
focusNext :: Stack -> Stack One has the focus
focusNext (w:ws) = ws ++ [w]
focusnext [] = [] Pattern matching
forces us to think
of all cases
Definition in Prelude
(implicitly imported)
Recursive call
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
[1,2] ++ [4,5]
= (1:2:[]) ++ (4:5:[])
= 1 : ((2:[]) ++ (4:5:[]))
= 1 : 2 : ([] ++ (4:5:[]))
= 1 : 2 : 4 : 5 : []
A ring of windows
One has the focus
Function application
binds more tightly than anything else:
(reverse xs) ++ [x]
focusPrev :: Stack -> Stack
focusPrev ws = reverse (focusNext (reverse ws))
(f . g) x = f (g x)
Functions as
arguments
c b a
f g
f.g
It‟s good to write tests as you write code
E.g. focusPrev undoes focusNext; swap
undoes itself; etc
module Stack where
...definitions...
...with a strange-
looking type
left right
Choices:
• no-op
• move focus to end
left right
left right
Warning: Pattern match(es) are non-exhaustive
In the definition of `focusPrev':
Patterns not matched: MkStk [] []
Patterns Values
data Maybe a = Nothing | Just a
Modules can be
grouped into
packages module Z where
f = ...
delete :: Stack w -> w -> Stack w
-- Remove a window from the stack
Extract addition
Pass on d to square
operation from d
You can build big instances by building on
smaller instances
class Eq a where
(==) :: a -> a -> Bool
instance Arbitrary a
=> Arbitrary [a] where Generate Nil value
arby r | even r1 = []
| otherwise = arby r2 : arby r3
where
(r1,r‟) = split r
(r2,r3) = split r‟ Generate cons value
Hey, what’s
Wild enthusiasm the big deal?
Despair Hack,
Incomprehension hack,
hack
Wadler/ Extensible
Multi- records (1996) Computation
Blott
parameter at the type
type
type classes level
classes
(1989) (1991) Functional
dependencies
(2000) Generic
Overlapping programming
instances
“newtype
deriving” Testing
Associated
types (2005)
Derivable
type classes Applications
Variations
A much more far-reaching idea than we
first realised: the automatic, type-driven
generation of executable “evidence”
Many interesting generalisations, still
being explored
Variants adopted in Isabel, Clean,
Mercury, Hal, Escher
Long term impact yet to become clear
All this pure stuff is very well, but sooner or
later we have to
talk to X11, whose interface is not at all pure
do input/output (other programs)
Configuration Layout
data algorithm
Events
(mouse, kbd,
client)
Window
placement
Session state
putStr :: String -> ()
Idea: -- Print a string on the console
Laziness!
A value of type (IO t) is an “action” that,
when performed, may do some input/output
before delivering a result of type t.
result :: a
IO a
World in World out
String String ()
getLine putStr
getLine :: IO String
putStr :: String -> IO () Main program is an
action of type IO ()
main :: IO ()
main = putStr “Hello world”
()
String
getLine putStr
Goal:
read a line and then write it back out
70
echo :: IO ()
echo = do { l <- getLine; putStr l }
()
String
getLine putStr
echo
72
getTwoLines :: IO (String,String)
getTwoLines = do { s1 <- getLine
; s2 <- getLine
; return (s1, s2) }
return :: a -> IO a
return
73
• “do” notation adds only syntactic sugar
• Deliberately imperative look and feel
74
echo :: IO ()
echo = do { l <- getLine; putStr l }
A “lambda abstraction”
(\x -> e) means
“a function taking one parameter, x, and returning e”
Run
QuickCheck on
Stack.hs all functions
called
“prop_xxx”
main :: IO ()
main = do { as <- getArgs
; mapM_ process as }
{ writeFile "script" $
unlines ([":l " ++ file] ++ concatMap makeTest tests)
; system ("ghci -v0 < script")
; return () }}
Import libraries
module Main where
Module Main must define
import System main :: IO ()
import List
main :: IO ()
main = do { as <- getArgs getArgs :: IO [String]
; mapM_ process as } -- Gets command line args
{ writeFile "script" (
unlines ([":l " ++ file] ++
concatMap makeTest tests))
lines
[“module Main where”, “import System”, ...]
map (fst.head.lex)
[“module”, “import”, ..., “prop_rev”, ...]
90
This call does not block
In the end we have to call C!
Calling convention Header file and name
of C procedure
Haskell
foreign import ccall unsafe "HsXlib.h XMapWindow"
mapWindow :: Display -> Window -> IO ()
mapWindow
calls XMapWindow Haskell name and type
of imported function
C
void XMapWindow( Display *d, Window *w ) {
...
}
All the fun is getting data across the border
data Display = MkDisplay Addr#
data Window = MkWindow Addr#
A gigantic (perhaps
infinite) tree of possible
moves
Generally, laziness unifies data with control
Laziness also keeps Haskell pure, which is a
Good Thing
Advanced types
• Unboxed types Concurrent Haskell
• Multi-parameter type classes (threads,
• Functional dependencies communication,
• GADTs synchronisation)
• Implicit parameters Software
• Existential types Transactional
• etc etc Memory (STM)
Template Haskell
(meta programming) Nested Data Parallel
Haskell Haskell
Rewrite rules language
(domain-specific
compiler extensions) Generic programming
One program that works
Monads, monad over lots of different
transformers, and arrows data structures
Programming
environments
Debugger
(emacs, vim,
Visual Studio)
Interpreters Space and
(e.g. GHCi, Hugs) time profiling
Compilers Generators
(e.g. GHC, Jhc, Yhc) • parser (cf yacc)
• lexer (cf lex)
• FFI
Haskell
language
Coverage Documentation
testing generation
(Haddock)
Testing
(e.g. QuickCheck, Hunit)
Packaging and
distribution
LIBRARIES (Cabal, Hackage)
Viewer written in Haskell using GTK binding
Yellow: not executed
Red: boolean gave False
Green: boolean gave True
A downloaded package, p, comes with
p.cabal: a package description
Setup.hs: a Haskell script to build/install
No effects
Useless
Dangerous Safe
Plan A
(everyone else)
Plan B
(Haskell)
No effects
Useless
Dangerous Safe
Arbitrary effects
Envy
Plan B
(Haskell)
No effects
Useless
Dangerous Safe
Plan A
(everyone else)
No effects
Useless
Dangerous Safe
One of Haskell‟s most significant
contributions is to take purity seriously, and
relentlessly pursue Plan B
Imperative languages will embody growing
(and checkable) pure subsets
Knowing functional programming makes you a
better Java/C#/Perl/Python/Ruby
programmer
The Haskell wikibook
http://en.wikibooks.org/wiki/Haskell