08. haskell functions

22
Functions Sebastian Rettig Every function in haskell consumes exactly one parameter and returns a value. Every function in haskell consumes exactly one parameter and returns a value.

Upload: sebastian-rettig

Post on 12-May-2015

168 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: 08. haskell Functions

Functions

Sebastian Rettig

Every function in haskell consumes exactly one parameter and returns a value.

Every function in haskell consumes exactly one parameter and returns a value.

Page 2: 08. haskell Functions

Functional Programming

● No Variables● Functions only, eventually stored in

Modules– Behavior do not change, once defined

– → Function called with same parameter calculates always the same result

● Function definitions (Match Cases)● Recursion (Memory)

Page 3: 08. haskell Functions

Haskell Features

● Pure Functional Programming Language● Lazy Evaluation ● Pattern Matching and Guards● List Comprehension● Type Polymorphism

Page 4: 08. haskell Functions

Nice to remember (1)

Typeclasses:● define properties of the types

● like an interface

– Eq can be compared

– Ord can be ordered (>, <, >=, <=) (extending Eq)

– Show can be shown as string

– Read opposite of Show

– Enum sequentially ordered types (can be enumerated

and usable in List-Ranges ['a'..'e'])

Page 5: 08. haskell Functions

Nice to remember (2)

Typeclass-Membership:

1. derive from existing Memberships of used types

data Vector2D = Vector Float Float deriving (Show, Eq)

2. implement Membership by your own

instance Show Vector2D where

show Vector a b = “x: ” ++ [a] ++ “ ; y: ” ++ [b]

Page 6: 08. haskell Functions

Curried Functions (1)● let's look at the Function header again, e.g:

max :: (Ord a) => a -> a -> a

1. we have a Typeclass restriction for Ord

2. we have 2 Parameters of Types, who have a membership for the Ord Typeclass

3. we have a return value of the same type● But, why is the syntax not separating the parameters

better from the result set?

Page 7: 08. haskell Functions

Curried Functions (2)● every function in haskell consumes exactly one

parameter and returns a value

● so we could write the function header instead of:

max :: (Ord a) => a -> a -> a

● also in the following way:

max :: (Ord a) => a -> (a -> a)

– max is a function which consumes a parameter and returns a function

– these function consumes a parameter and returns a value (the max of both values)

● → Partial Application

Page 8: 08. haskell Functions

Curried Functions (3)● some examples:

– :t max returns

max :: (Ord a) => a -> a -> a

– max 4 5 returns 5

– (max 4) 5 returns 5

– :t max 4 returns

max 4 :: (Num a, Ord a) => a -> a

– let foo = max 4

foo 5 returns 5

– :t max 4 5 returns

max 4 5 :: (Num a, Ord a) => a

Page 9: 08. haskell Functions

Curried Functions (4)● we can also partial apply infix functions

(/10) 2 returns 0.2

(10/) 2 returns 5

(++ “bar”) “foo” returns “foobar”

(“bar” ++) “foo” returns “barfoo”

:t (`elem` ['a'..'z'])(`elem` ['a'..'z']) :: Char -> Bool

:t ('a' `elem`)

(`elem` ['a'..'z']) :: [Char] -> Bool

:t elem

elem :: Eq a => a -> [a] -> Bool

Page 10: 08. haskell Functions

Pointless Style● let's say, we have the following function:

maxWithFour :: (Num a, Ord a) => a -> a

maxWithFour x = max 4 x

● what is the result of max 4 again?

:t max 4 returns max 4 :: (Num a, Ord a) => a -> a

● max 4 returns already a function which consumes a parameter, so we can simplify our function:

maxWithFour :: (Num a, Ord a) => a -> a

maxWithFour = max 4

● but how can we achieve that with the following function?

fn x = ceiling (negate (tan (cos (max 50 x))))

Page 11: 08. haskell Functions

Function Application (1)● used with ($)

● has the following header::t ($)

($) :: (a -> b) -> a -> b

● compared with SPACE (normal function application)

– ($) has lowest priority

– ($) is right associative f $ g $ a b = (f (g (a b)))

– SPACE has highest priority

– SPACE is left associative f a b c = (((f a) b) c)

Page 12: 08. haskell Functions

Function Application (2)● what can we do with ($) ?

● helps us to avoid parentheses:

– instead of:sum (map sqrt [1..20])

– we can write:sum $ map sqrt [1..20]

● allows us also to wrap a value in a function:

map ($ 3) [(4+), (10*), (^2), sqrt] returns [7.0,30.0,9.0,1.7320508075688772]

Page 13: 08. haskell Functions

Function Composition (1)

● Definition:

● used with (.)

● has the following header::t (.)

(.) :: (b -> c) -> (a -> b) -> a -> c

● composing two functions produces a new function

● good for on-the-fly pass of a function to the next function

Page 14: 08. haskell Functions

Function Composition (2)● what can we do with (.) ?

● helps us also to avoid parentheses

● → unwraps the parameter out of parentheses

– instead of:map (\xs -> negate (sum (tail xs))) [[1..5],[3..6],[1..7]]

– we can write:map (negate . sum . tail) [[1..5],[3..6],[1..7]]

Page 15: 08. haskell Functions

Composition vs. Application (1)● IMPORTANT to know the difference between ($) and (.)

● best to compare both headers again:

– ($) :: (a -> b) -> a -> b

– (.) :: (b -> c) -> (a -> b) -> a -> c

● combination of both allows us parenthesis-less writing

● shorter code and mostly easier to read

● → possibility to write pointless-style functions with more then one function call

Page 16: 08. haskell Functions

Composition vs. Application (2)● example with parameter:

– foo xs = sum (filter (> 10) (map (*2) xs))

– foo xs = sum $ filter (> 10) $ map (*2 ) xs

● example without parameter (pointless-style):– foo xs = sum (filter (> 10) (map (*2) xs))

– foo = sum . filter (> 10) . map (*2)

Page 17: 08. haskell Functions

Useful Types● Maybe:

data Maybe a = Nothing | Just a

– contains maybe a type a or Nothing

– good for handling e.g. Hashmap lookup

● Nothing if key not exist, else Value of type a● Either:

data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show)

– can contain type a or type b – Left for e.g. Error Messages, Right for value

– like an extended Maybe with information for Nothing

Page 18: 08. haskell Functions

Functor Typeclass (1)class Functor f wherefmap :: (a -> b) -> f a -> f b

● for things that can be mapped over

● !!! Functor needs Types with 1 Typeparameter !!!

● fmap gets a function and a type and maps the function over the type variable

● Instance for List:

– Remember: List has 1 Typeparameter [a], but is just Syntactic Sugar for ([] a)

instance Functor [] wherefmap = map

– Example: fmap (*2) [2,3,4] returns [4,6,8]

Page 19: 08. haskell Functions

Functor Typeclass (2)class Functor f wherefmap :: (a -> b) -> f a -> f b

● Instance for Maybe

instance Functor Maybe wherefmap g (Just x) = Just (g x) fmap g Nothing = Nothing

● Example:

– fmap (+3) Nothing returns Nothing

– fmap (+3) (Just 4) returns (Just 7)

Page 20: 08. haskell Functions

Functor Typeclass (3)class Functor f wherefmap :: (a -> b) -> f a -> f b

● Instance for Either

instance Functor (Either a) wherefmap f (Right x) = Right (f x)fmap f (Left x) = Left x

● Either is a type with 2 Typeparameters!

● → we have to permanently include the first parameter in the instance (curried function, partial application)

● → fmap do not change the 1st Typeparameter, only the 2nd

● → Left Type-Constructor of Either is often used for Error Messages

Page 21: 08. haskell Functions

Functor Typeclass (4)class Functor f wherefmap :: (a -> b) -> f a -> f b

● Example:

– fmap (+3) (Left 4) returns (Left 4)

– fmap (+3) (Right 4) returns (Right 7)

● what happens, if we try to do that?fmap (+) (Just 4)

● let's look at the type: :t fmap (+) (Just 4)fmap (+) (Just 4) :: Num a => Maybe (a -> a)

● partial application, BUT we can not use the Functor instance on the result!

● → we need an extension → Applicative Functors

Page 22: 08. haskell Functions

Sources

[1] Haskell-Tutorial: Learn you a Haskell (http://learnyouahaskell.com/, 2012/03/15)

[2] The Hugs User-Manual (http://cvs.haskell.org/Hugs/pages/hugsman/index.html, 2012/03/15)

[3] The Haskellwiki (http://www.haskell.org/haskellwiki, 2012/03/15)