FunctionalProgramming_Haskell-Feb262009

Document Sample

Shared by: Zoe Flower
Categories
Tags
Stats
views:
23614
posted:
4/7/2009
language:
English
pages:
42
Functional Programming and Haskell

Erik Charlebois

Slant Six Games



March 5th, 2009



Outline



Functional Programming Core Concepts



Haskell Haskell Language Haskell Features



Real World Functional Programming



Functional Programming



Higher Order Functions



Functions can take functions as arguments and return them as results.



Higher Order Functions



Functions can take functions as arguments and return them as results.

> :type map map :: (a -> b) -> [a] -> [b] > let add1 x = x + 1 > map add1 [1,2,3] [2,3,4]



Higher Order Functions



Functions can take functions as arguments and return them as results.

> :type map map :: (a -> b) -> [a] -> [b] > let add1 x = x + 1 > map add1 [1,2,3] [2,3,4]



> let addn n = \x -> x + n > map (addn 2) [1,2,3] [3,4,5]



Purity



Functions take some input and generate some output with no observable side effects.



Purity



Functions take some input and generate some output with no observable side effects.

// Oops... int add(int x, int y) { launch_missiles(); return x + y; }



Purity



Functions take some input and generate some output with no observable side effects.

// Oops... int add(int x, int y) { launch_missiles(); return x + y; }



-- Compile error! let add x y = case launch_missiles of _ -> x + y



Recursion



Functions invoke themselves to perform iteration.



Recursion



Functions invoke themselves to perform iteration.

-- Inductive definition for map map fn [] = [] map fn (x:xs) = (fn x) : (map fn xs)



Recursion



Functions invoke themselves to perform iteration.

-- Inductive definition for map map fn [] = [] map fn (x:xs) = (fn x) : (map fn xs)



-- Inductive definition for left fold foldl :: (a -> b -> a) -> a -> [b] -> a foldl fn a [] = a foldl fn a (x:xs) = foldl fn (fn a x) xs sum ls = foldl (+) 0 ls product ls = foldl (*) 1 ls



Strictness Arguments can be evaluated prior to a call (eager) or as needed (lazy).



Strictness Arguments can be evaluated prior to a call (eager) or as needed (lazy).

-- Custom control flow constructs. myif True tp _ = tp myif False _ fp = fp



Strictness Arguments can be evaluated prior to a call (eager) or as needed (lazy).

-- Custom control flow constructs. myif True tp _ = tp myif False _ fp = fp



-- Out of order definition. let x = y + 1; y = 3 in x



Strictness Arguments can be evaluated prior to a call (eager) or as needed (lazy).

-- Custom control flow constructs. myif True tp _ = tp myif False _ fp = fp



-- Out of order definition. let x = y + 1; y = 3 in x



-- Cyclic data structures. > let x = 1 : 2 : 3 : x > x [1,2,3,1,2,3,1,2,3,1,2,3,1,...] > take 10 x [1,2,3,1,2,3,1,2,3,1]



Haskell



Haskell



Inspired by Miranda Originally a platform for programming language research Standardized in 1998 as Haskell 98 Development of primary compiler funded by Microsoft Research



Haskell



Inspired by Miranda Originally a platform for programming language research Standardized in 1998 as Haskell 98 Development of primary compiler funded by Microsoft Research Pure, lazy functional programming language Garbage-collected Statically-typed Compiled or interpreted



Currying



A function can be called without all of its arguments. A new function is returned which takes the remaining arguments.



Currying



A function can be called without all of its arguments. A new function is returned which takes the remaining arguments.

> map (+ 1) [1,2,3] [2,3,4] > let addntolist n = map (+ n) > addntolist 8 [1,2,3] [9,10,11]



Algebraic Data Types



Union types done right.



Algebraic Data Types



Union types done right.

data Color = Red | Green | Blue data Maybe a = Nothing | Just a data Tree a = Node (Tree a) (Tree a) | Leaf a



Algebraic Data Types



Union types done right.

data Color = Red | Green | Blue data Maybe a = Nothing | Just a data Tree a = Node (Tree a) (Tree a) | Leaf a



-- Pattern matching is used to access the members. findFirstRed :: Tree (Color, t) -> Maybe t findFirstRed (Leaf (Red, n)) = Just n findFirstRed (Leaf _) = Nothing findFirstRed (Node left right) = case findFirstRed left of Nothing -> findFirstRed right Just n -> Just n



Type Classes Families of functions defined for multiple types. Similar to C++ templates, but polymorphic!



Type Classes Families of functions defined for multiple types. Similar to C++ templates, but polymorphic!

class Show a where show :: a -> String class Monoid a where mempty :: a mappend :: a -> a -> a class Foldable t where fold :: Monoid m => t m -> m



Type Classes Families of functions defined for multiple types. Similar to C++ templates, but polymorphic!

class Show a where show :: a -> String class Monoid a where mempty :: a mappend :: a -> a -> a class Foldable t where fold :: Monoid m => t m -> m



data Tree a = Node (Tree a) (Tree a) | Leaf a instance Foldable Tree where fold (Leaf a) = a fold (Node a b) = fold a ‘mappend‘ fold b > fold (Node (Node (Leaf 3) (Leaf 4)) (Leaf 5)) 12 :: Integer



Type Inferencing Types do not need to be declared. They can be inferred from the surrounding context.



Type Inferencing Types do not need to be declared. They can be inferred from the surrounding context.

> :type read read :: forall a. (Read a) => String -> a > :type 1 1 :: forall t. (Num t) => t



Type Inferencing Types do not need to be declared. They can be inferred from the surrounding context.

> :type read read :: forall a. (Read a) => String -> a > :type 1 1 :: forall t. (Num t) => t



> let add1ToString str = 1 + read str add1ToString :: forall t. (Num t, Read t) => String -> t



Type Inferencing Types do not need to be declared. They can be inferred from the surrounding context.

> :type read read :: forall a. (Read a) => String -> a > :type 1 1 :: forall t. (Num t) => t



> let add1ToString str = 1 + read str add1ToString :: forall t. (Num t, Read t) => String -> t



> add1ToString "22" 23 :: Integer > add1ToString "22" :: Int 23 :: Int



What I Like About Haskell



100 times faster than your typical scripting language Strict typing, no pointers Less (finger) typing! More (compile-error) typing! Garbage collection Programmable control flow Tractable side effects – makes concurrency sane! Software transactional memory



Real World Functional Programming



Applications Research

Formal verification Parallelism Type theory



Commercial

Financial sector (Credit Suisse) Security and encryption (Galois) Hardware design (Bluespec) Procedural city generation (gamr7) Multimedia content creation (Anygma)



Open Source

Languages (GHC, Pugs) Window Manager (xmonad) Source Control (darcs) Build System, Packaging (cabal) Web Applications (happs, hoogle)



FP Issues in Game Development



No console ports Not designed for embedded systems Core loop performance High memory consumption Wrong garbage collector tradeoffs



What could FP be used for?



What could FP be used for? Tools! Parsers, domain specific languages, data munging, build systems, code generation.



What could FP be used for? Tools! Parsers, domain specific languages, data munging, build systems, code generation. Ideas! Region-based garbage collection is a reasonable approach to memory management; Insomniac does this. Purity makes parallel programming sane. Pure is the right default for a parallel world. Many beneficial functional programming idioms can be simulated with C++ templates.



What could FP be used for? Tools! Parsers, domain specific languages, data munging, build systems, code generation. Ideas! Region-based garbage collection is a reasonable approach to memory management; Insomniac does this. Purity makes parallel programming sane. Pure is the right default for a parallel world. Many beneficial functional programming idioms can be simulated with C++ templates. Scripting! Lua is Scheme without the parentheses; easy to program functionally.



Further Reading Haskell book http://book.realworldhaskell.org Official site http://www.haskell.org Package database http://hackage.haskell.org Type theory book http://www.cis.upenn.edu/~bcpierce/tapl/ Questions?



Monads Controlled side effects through typing. A design pattern for combining functions.

-- class Monad m where -return :: a -> m a -(>>=) :: m a -> (a -> m b) -> m b data State s a = State (s -> (s, a)) instance Monad (State s) where return a = State (\s -> (s, a)) (>>=) (State lhs) rhs = State (\s -> case lhs s of (s’, a) -> case rhs a of (State fn) -> fn s’) getState getState putState putState runState runState :: State s s = State (\s -> (s,s)) :: s -> State s () s’ = State (\s -> (s’, ())) :: State s a -> s -> (s, a) (State fn) a = fn a



Monads Now we can glue functions that require a common state together and run them with an initial state!

incrementBy1 = getState >>= \s -> putState (s + 1) morefun_nosugar = incrementBy1 >>= \_ -> getState >>= \s -> incrementBy1 >>= \_ -> -- has no effect putState s -- because we put an old state here morefun_withsugar = do incrementBy1 s runfun 11 :: Integer




Share This Document


Other docs by Zoe Flower
FunctionalProgramming_Haskell-Feb262009
Views: 23614  |  Downloads: 3
gplt_presentation
Views: 23240  |  Downloads: 1
Montreal Game Summit 2008
Views: 17  |  Downloads: 1
Montreal Game Summit 2008 Presentation - No Notes
Views: 24445  |  Downloads: 12
Audio Rendering Parameter Generation on the SPU
Views: 24443  |  Downloads: 7
by registering with docstoc.com you agree to our
privacy policy

You are almost ready to download!

You are almost ready to download!