08. haskell functions
TRANSCRIPT
![Page 1: 08. haskell Functions](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/1.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/2.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/3.jpg)
Haskell Features
● Pure Functional Programming Language● Lazy Evaluation ● Pattern Matching and Guards● List Comprehension● Type Polymorphism
![Page 4: 08. haskell Functions](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/4.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/5.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/6.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/7.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/8.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/9.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/10.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/11.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/12.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/13.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/14.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/15.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/16.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/17.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/18.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/19.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/20.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/21.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022042423/5550f38ab4c905417d8b5579/html5/thumbnails/22.jpg)
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)