View
287
Download
4
Category
Preview:
DESCRIPTION
Explains why functional programming is back and shows some features from Haskell that are being ported to other languages. Presented at ThoughtWorks Brazil Away Day 2011.
Citation preview
Functional Programming with Haskell
Adriano Bonatabonat@thoughtworks.com
@tanob
Why FP?
• Source of new ideas
• Expressiveness
• Multi-core CPUs
• Different paradigm
New ideas:Garbage collection (LISP)Type inference (simply typed lambda calculus)GenericsType classes
Expressiveness:DSLs
What is it?
• Different programming paradigm
• OO
• Logic
• Procedural
• Functions are the main element in the language
Function applications“Functional programming is so called because a program consists entirely of functions. [...]
Typically the main function is defined in terms of other functions, which in turn are defined in terms of still more functions, until at the bottom level the functions are language primitives.”
John Hughes, 1989 - Why functional programming matters
OriginAlonzo Church developed Lambda
Calculus as part of his investigations on Math foundations
on 1936.
Lambda Calculus
• Variables
• Expressions (e1 e2)
• Lambda abstractions (λx. e)
Lambda Calculus (I)
• true = λxy. x
• false = λxy. y
• NOT a = (a)(false)(true)
• a AND b = (a)(b)(false)
• a OR b = (a)(true)(b)
• a XOR b = (a)((b)(false)(true))(b)
Haskell
• Academic origin
• Named in honor of Haskell Curry
• Defined by a committee
• First version released on 98 (Haskell 98)
Features• Pureness
• Type Inference
• Algebraic datatypes (ADTs)
• Pattern Matching
• Lazyness
• High Order Functions
• Currification (aka Partial Application)
• Type Classes
• Monads
Pureness
• No side-effects
• A function call can have no effect other than to compute its result
• Expressions can be evaluated at any time
• Programs are “referentially transparent”
Good for:* reasoning* compiler optimization* concurrency
Type Inference
Let’s see the types for these declarations:four = 4add x y = x + yemphasize x = x ++ “!”
Algebraic datatypesEnumeration:data Season = Summer | Winter | Autumn | Spring
Product:data Pair = Pair Int Int
Sum:data Shape = Circle Float | Rect Float Float
Polymorfic & Recursive:data Tree a = Leaf a | Node (Tree a) (Tree a)
Algebraic datatypes (I)
data Maybe a = Nothing | Just adata Either a b = Left a | Right b
Pattern Matching
Definition:sum [] = 0sum (elem:rest) = elem + sum rest
Application:sum [1,2,3,10]
Pattern Matching (I)
area (Circle rad) = pi * rad ^ 2area (Rect width height) = width * height
first (Pair value _) = value
High Order Functions
Functions which at least:
• Receive functions as parameters
• Return functions (aka curried functions)
High Order Functions (I)
map :: (a -> b) -> [a] -> [b]map f [] = []map f (x:xs) = f x : map f xs
Currification
add :: Int -> Int -> Intadd x y = x + y
inc :: Int -> Intinc = add 1
Lazyness
• aka “call by need”
• Expressions can be evaluated when necessary
• Allows the use of infinite lists
Being pure helps here
Lazyness (I)
Definition:even_numbers :: [Int]even_numbers = filter even [1..]
Application:take 5 even_numbers
Lazyness (II)
fibs :: [Int]fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
From: http://en.wikipedia.org/wiki/Lazy_evaluation
Type Classes
• Created to solve the problem with numeric operator overload and equality testing
• Some type classes defined by Haskell 98:
• Eq
• Read/Show
Type Classes (I)
class Eq a where(==), (/=) :: a -> a -> Boolx == y = not (x /= y)x /= y = not (x == y)
You can define what is called a “minimal implementation”.
Type Classes (II)data User = User { name :: String }
instance Eq User whereuser1 == user2 = name user1 == name user2
instance Show User whereshow user = name user
Automatic Derivation
data Season = Summer | Winter | Autumn | Springderiving (Show, Eq)
show Summer> “Summer”
Summer /= Winter> True
Monads
• Adds to the type system a way to describe actions
• The actions will happen in a certain order
Monads
• Common monads:
• IO
• State
• Reader
• Maybe
Monads
thing1 >>= \x ->func1 x >>= \y ->
thing2 >>= \_ ->func2 y >>= \z ->
return z
do x <- thing1 y <- func1 x thing2 z <- func2 y return z
sugar no-sugar
Monads
class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a
“return” is a bad name, it actually injects a value into the monadic type.
Logger Monadtype Log = [String]
data Logger resultType = Logger (resultType, Log) deriving Show
record x = Logger ((), [x])
instance Monad Logger where return value = Logger (value, []) prevLogger >>= nextAction = let Logger (prevResult, prevLog) = prevLogger Logger (newResult, newLog) = nextAction prevResult in Logger (newResult, prevLog ++ newLog)
Testing?
• Go read about QuickCheck!
Want to learn more?
Freely available online:http://book.realworldhaskell.org/
Your Knowledge Portfolio
"Learn at least one new language every year. [...] Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut."
The Pragmatic Programmer
Functional Programming with Haskell
Adriano Bonatabonat@thoughtworks.com
@tanob
Recommended