Sunteți pe pagina 1din 66

Introduction to Weird Functional Languages with

Haskell

Alex “saterus” Burkhart


The Ohio State University
Open Source Club

2011-05-19
Introduction to Weird Functional Languages with Haskell
Table of Contents

Functional Programming
The Functional Paradigm
Haskell
Basic Syntax
Custom Data Structures
Typeclasses
List
Pattern Matching
Binary Tree
Think Functionally
Common Patterns
Recursion with Lists
Functors
Functions as Arguments
Applicative Functors
Higher Order Functions
Monoids
Lambdas
Future Topics
Currying
Where to go to Learn More
Flip
Function Composition
Laziness
Functional Programming

Functional Programming
Functional Programming – The Functional Paradigm

I Declarative
I First Class Functions
I Pure Functions
I Immutibility
I Parallelism
Functional Programming – The Functional Paradigm

Declarative
I “What” instead of “How”

I Smart Compilers

I Safety and Correctness


Functional Programming – The Functional Paradigm

First Class Functions


I Functions as Data Structures

I Use Functions as Arguments to Other Functions

I Abstract Common Patterns


Functional Programming – The Functional Paradigm

Pure Functions
I No I/O or Modification of State

I Consistent, Predictible Results

I Safety

I Optimization
Functional Programming – The Functional Paradigm

Immutability
I Can’t Change Data

I Immutable Structures can be Shared

I Reusing List Links


Functional Programming – The Functional Paradigm

Parallelism
I Locks Unnecessary

I Order of Execution negotiated by Compiler


Functional Programming – The Functional Paradigm

Extra Stuff
I Code Generation with Lisp

I Type Safety with Haskell and OCaml

I Massive Paralellism with Erlang

I Haskell, Erlang, OCaml are all fast


Haskell

Haskell
Haskell – Basic Syntax

Basic Data Structures


I Bool, Char, Numbers, List, String, Tuples,

Functions
I True and False

I ’a’ through ’z’ and more

I Ratios and Arbitrary Size Numbers

I [1, 2, 3]

I (1, 3)

I (+), sum
Haskell – Basic Syntax

Function Signatures
I 12 :: Int

I [1, 2, 3] :: [Integer]

I [’f’, ’o’, ’o’] :: String

I (1, 3) :: (Int, Int)

I (+) :: Int -> Int -> Int

I sum :: [Integer] -> Integer


Haskell – Basic Syntax

Algebraic Data Types


I data Bool = True | False

I data Int = -2147483648 | -2147483647 | ... | -1

| 0 | 1 | 2 | ... | 2147483647
I data Color = Red | Green | Blue

I data TrafficLight = Light String String Color

I data Maybe a = Nothing | Just a

I data Either a b = Left a | Right b


Haskell – Basic Syntax

Function Definitions
I even :: Integer -> Integer -> Bool

even x = (mod x 2) == 0
I odd :: Integer -> Integer -> Bool

odd x = not (even x)


I doubleMe x = x + x
Haskell – Typeclasses

The Problem
I Function Scope

I Equality for the Color type

(==) :: Color -> Color -> Bool


(==) colorA colorB = ...
Haskell – Typeclasses

The Solution
I Ad-hoc polymorphic interfaces

I class Eq a where

(==) :: a -> a -> Bool


(/=) :: a -> a -> Bool
I instance Eq Color where

(==) :: Color -> Color -> Bool


(==) a b = ...
(/=) :: Color -> Color -> Bool
(/=) a b = not (a == b)
Haskell – Typeclasses

The Win
I Typeclass Deriving

I data Color = Red | Green | Blue

deriving (Eq, Show, Read)


I Automatically derive instances of Read, Show,

Bounded, Enum, Eq, and Ord.


Haskell – Typeclasses

Function Signatures Updated


I 12 :: (Num a) => a

I [1,2,3] :: (Num a) => [a]

I even :: Integral a => a -> a -> Bool

I sort :: (Ord a) => [a] -> [a]


Haskell – Pattern Matching

Avoid lot’s of manual == comparisons


I data Color = Red | Green | Blue

I Implement Show

I Implement (==)
Haskell – Pattern Matching

I data Color = Red | Green | Blue


I show :: Color -> String
show Red = “Red”
show Green = “Green”
show Blue = “Blue”
Haskell – Pattern Matching

I data Color = Red | Green | Blue


I (==) :: Color -> Color -> Bool
(==) Red Red = True
(==) Green Green = True
(==) Blue Blue = True
(==) _ _ = False
Haskell – Pattern Matching

data Maybe a = Nothing | Just a


I val1 = Just 73

I val2 = Nothing

I possiblyDouble :: Maybe Int -> Maybe Int

possiblyDouble x = undefined
Haskell – Pattern Matching

data Maybe a = Nothing | Just a


I val1 = Just 73

I val2 = Nothing

I possiblyDouble :: Maybe Int -> Maybe Int

possiblyDouble Nothing = Nothing


possiblyDouble (Just x) = x + x
Haskell – Pattern Matching

Matching inside Lists


I myList = [1,2,3,4,5]

I sum :: [Int] -> Int -> Int

sum [] acc = acc


sum [x:xs] acc = sum xs (acc + x)
Haskell – Pattern Matching

Matching with Case Statements


I val1 = Just 73

I val2 = Nothing

I possiblyDouble :: Maybe Int -> Maybe Int

possibleDouble x = case x of
Nothing -> Nothing
(Just x) -> x + x
Haskell – Pattern Matching

Guards
I val1 = 5

I val2 = 9001

I doubleSmall :: Int -> Int

doubleSmall x
| x <= 9000 = x + x
| otherwise = x
Think Functionally

Think Functionally
Think Functionally – Recursion with Lists

I myList = [1,2,3,4,5]
I sum :: [Int] -> Int -> Int
sum [] acc = acc
sum [x:xs] acc = sum xs (acc + x)
Think Functionally – Functions as Arguments

I myList = [1,2,3,4,5]
I double :: Int -> Int
I map :: (a -> b) -> [a] -> [b]
Think Functionally – Functions as Arguments

I example = “things”
I toUpper :: Char -> Char
I map :: (a -> b) -> [a] -> [b]
Think Functionally – Functions as Arguments

I myList = [1,2,3,4,5]
I foldl :: (a -> b -> a) -> a -> [b] -> a
I sum = ?
Think Functionally – Higher Order Functions

I map :: (a -> b) -> [a] -> [b]


I filter :: (a -> Bool) -> [a] -> [a]
I zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
I foldl :: (a -> b -> a) -> a -> [b] -> a
I foldl1 :: (a -> a -> a) -> [a] -> a
I foldr :: (a -> b -> b) -> b -> [a] -> b
I foldr1 :: (a -> a -> a) -> [a] -> a
I any :: (a -> Bool) -> [a] -> Bool
I all :: (a -> Bool) -> [a] -> Bool
Think Functionally – Lambdas

I myList = [1,2,3,4,5]
I triple = map (\x -> x + x + x) myList
I divisThree = filter (\x -> (mod x 3) == 0)
myList
Think Functionally – Currying

I ghci> :t (+)
(+) :: Num a => a -> a -> a
ghci> :t (+ 1)
(+ 1) :: Num a => a -> a
I applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
Think Functionally – Flip

I flip :: (a -> b -> c) -> b -> a -> c


I flip f x y = f y x
Think Functionally – Flip

I myDiv :: Fractional a => a -> a -> a


I myDiv xy=x/y
I myDiv 3 12
=> ?
I myDiv 36 12
=> ?
Think Functionally – Flip

I flip :: (a -> b -> c) -> b -> a -> c


I myDiv :: Fractional a => a -> a -> a
I ghci> :t flip myDiv
=> ?
I flip myDiv 3 12
=> ?
I flip myDiv 36 12
=> ?
Think Functionally – Function Composition

I (f ◦ g)(x ) ≡ f (g(x )) – math, not Haskell


I (.) :: (b -> c) -> (a -> b) -> a -> c
I f . g = \x -> f (g x)
I map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19]
=> [-5,-3,-6,-7,-3,-2,-19]
I map (negate . abs) [5,-3,-6,7,-3,2,-19]
=> [-5,-3,-6,-7,-3,-2,-19]
Think Functionally – Laziness

Delayed Computation Until Necessary


I Programs are Transformations of Data

I Infinite Data Structures

I Interesting Compiler Optimizations

I “undefined”

I Circular Structures

I Unique to Haskell
Think Functionally – Laziness

Infinite Data Structures


I Haskell Ranges

1.. :: (Num t) => [t]


I take 5 [1..]

I length [1..] – Bad Idea

I fac 0 = 1

fac n = n * fac (n - 1)
I fib = 0 : 1 : zipWith (+) fib (tail fib)
Think Functionally – Laziness

Short cut Fusion


I map f (map g someList)

=> map (f . g) someList


Think Functionally – Laziness

undefined
I Valid as long as unevaluated

I Stub out function signatures


Think Functionally – Laziness

Circular Structures
I No mutable references

I data Foo = Bar a Foo

I circularFoo :: Foo Int

circularFoo = x
where x = Bar 1 y
y = Bar 2 x
I Sci-Fi-Explanation: “You can borrow things

from the future as long as you don’t try to


change them”
Custom Data Structures

Custom Data Structures


Custom Data Structures – List

I data List a = Nil | Cons a (List a)


I head :: List a -> Maybe a
head Nil = Nothing
head (Cons x _) = Just x
I map :: (a -> b) -> List a -> List b
map _ Nil = Nil
map f (Cons x xs) = Cons (f x) (map f xs)
Custom Data Structures – Binary Tree

I data Tree a = Leaf a | Node (Tree a) (Tree a)


I testTree = Node (Node (Leaf 2) (Node (Node
(Leaf 12) (Leaf 7)) (Leaf 3))) (Leaf 9)
I tMap :: (a -> b) -> Tree a -> Tree b
tMap f (Leaf x) = Leaf (f x)
tMap f (Node l r) = Node (tMap f l) (tMap f r)
Custom Data Structures – Binary Tree

I tFilter :: (a -> Bool) -> Tree a -> [a]


tFilter f (Leaf x)
| f x = [x]
| otherwise = []
tFilter f (Node l r) = (tFilter f l) ++ (tFilter f l)
Custom Data Structures – Binary Tree

I tFoldDf :: (a -> b -> a) -> a -> Tree b -> a


tFoldDf f acc (Leaf x) = f acc x
tFoldDf f acc (Node l r) = tFoldDf f (tFoldDf f
acc l) r
I treeMax t = tFoldDf max 0 t
I treeMin t = tFoldDf min 0 t
Custom Data Structures – Binary Tree

I member :: (Eq a) => Tree a -> a -> Maybe a


member t e = tFoldDf member’ Nothing t
where member’ acc x
| x == e = Just x
| otherwise = acc
Common Patterns

Common Patterns
Common Patterns – Functors

I map :: (a -> b) -> [a] -> [b]


I lmap :: (a -> b) -> List a -> List b
I tMap :: (a -> b) -> Tree a -> Tree b
Common Patterns – Functors

I class Functor a where


fmap :: Functor f => (a -> b) -> f a -> f b
I instance Functor [a] where
fmap :: (a -> b) -> [a] -> [b]
fmap = map
I instance Functor (Tree a) where
fmap :: (a -> b) -> Tree a -> Tree b
fmap = tMap
Common Patterns – Functors

I class Functor a where


fmap :: Functor f => (a -> b) -> f a -> f b
I instance Functor Maybe where
fmap :: (a -> b) -> Maybe a -> Maybe b
fmap _ Nothing = Nothing
fmap f Just x = Just (f x)
I possiblyDouble m = fmap double m
where double x = x + x
Common Patterns – Functors

I Recall Currying...
I plusX m = fmap plux m
where plux x = (+ x)
I uh oh...
I ghci> :t plusX [1,2,3,4,5]
plusX [1,2,3,4,5] :: Num a => [a -> a]
Common Patterns – Applicative Functors

I ghci> :t plusX [1,2,3,4,5]


plusX [1,2,3,4,5] :: Num a => [a -> a]
I fmap again?
I class (Functor f) => Applicative f where pure
:: a -> f a (<*>) :: f (a -> b) -> f a -> f b
I plusX [1,2,3,4] <*> [10]
Common Patterns – Applicative Functors

I instance Applicative Maybe where pure = Just


Nothing <*> _ = Nothing (Just f) <*>
something = fmap f something
I pure (+3) <*> Just 9
I Just (++"hahah") <*> Nothing
I Nothing <*> Just "woot"
I pure (+) <*> Just 3 <*> Just 5
Common Patterns – Monoids

Monoids
I class Monoid a where

mempty :: Monoid a => a


mappend :: Monoid a => a -> a -> a
mconcat :: Monoid a => [a] -> a
I instance Monoid [a] where

mempty = []
mappend = (++)
mconcat = foldr mappend mempty
Common Patterns – Monoids

I instance (Monoid a) => Monoid (Maybe a)


where
mempty = Nothing
mappend Nothing x = x
mappend x Nothing = x
mappend (Just x) (Just y)
= Just (x `mappend` y)
Common Patterns – Future Topics

I “newtype”, “type”, ($), and Record Syntax


I Numeric Type Heirarchy and ByteStrings
I Monads
I Common Monads (I/O, Reader, Writer, State)
I MonadTransformers and MonadPlus
I Arrows
I Parser Combinators
I Category Theory and Advanced Types
I Advanced Functional Data Structures
I Trees as Maps
I Zippers
I Finger Trees (will blow your mind)
Common Patterns – Future Topics

I Testing/Quickcheck
I Error Handling
I Mutable Objects and Arrays
I Parallel Programming and STM
I Functional Reactive Programming
I Foreign Function Interface
I Cabal and Hackage
I Examine Real Code
I XMonad Window Manager (<1000 lines)
I Parsec
I Yesod Web Framework
I Darcs, Version Control System
I The Glorious Glasgow Haskell Compiler
I Agda Theorem Prover
Where to go to Learn More

Where to go to Learn More


Where to go to Learn More

I Learn You a Haskell for Great Good! 1

I Real World Haskell 2

I Haskell Wikibook 3

I Write Yourself a Scheme in 48 Hours 4

1
HTML:
http://learnyouahaskell.com/
2
HTML:
http://book.realworldhaskell.org/
3
HTML:
https://secure.wikimedia.org/wikibooks/en/wiki/Haskell
4
HTML:
http://halogen.note.amherst.edu/~jdtang/scheme_in_48/tutorial/
overview.html
Where to go to Learn More

I Hackage Package Repository 1

I Hoogle API Search 2

I Hayoo API Search 3

I #Haskell IRC Channel 4

1
HTML:
http://hackage.haskell.org/
2
HTML:
http://haskell.org/hoogle/
3
HTML:
http://holumbus.fh-wedel.de/hayoo/hayoo.html
4
HTML:
http://www.haskell.org/haskellwiki/IRC_channel
Thanks

Thanks
Thanks

Latex template and tech support:


I Daniel “paradigm” Thau

For teaching me Haskell and providing some of my


examples:
I BONUS, Learn You a Haskell

I Bryan O’Sullivan, Don Stewart, and John

Goerzen, Real World Haskell

S-ar putea să vă placă și