Higher order Functions
1 Parentheses!? atHome
Give examples for functions with the following types:
(Float −> Float) −> Float
Float −> (Float −> Float)
(Float −> Float) −> (Float −> Float)-- For example (all these expressions have more general polymorphic types, but, in particular, type check at the requested types)
\f -> f 2.0 :: (Float −> Float) −> Float
(*) :: Float −> (Float −> Float)
(.) (+1) :: (Float −> Float) −> (Float −> Float) Give an example program p with the following type and explain how the function arrow -> associates:
p :: Int -> Bool -> Int-- For example
p i b = if b then i else -i
-- Indeed, the function arrow -> always associates to the right, so this type should be read as
-- the type Int -> (Bool -> Int) of curried multiple argument functions, rather than the type (Int -> Bool) -> Int of higher order functionsGive examples of programs foo, bar and baz, such that foo bar baz type checks and please explain how function application associates.
-- For example,
foo :: Int -> Int -> Int
foo = (+)
bar :: Int
bar = 1
baz :: Int
baz = 2
-- Then foo bar baz is well-typed at type Int
-- Indeed, function application always associates to the left so the expression should be read as (foo bar) baz
-- Another example would be
foo :: (a -> [a] -> [a]) -> [a] -> [a] -> [a]
foo = foldr
bar :: a -> [a] -> [a]
bar a as = as ++ [a]
baz :: [a]
baz = []
-- Then, foo bar baz (which should be read as (foo bar) baz) has type [a]
-- Note that function application associating to the left and function arrows associating to the right are nice behaviour because it means
-- that we can implement the default use-case of curried functions of multiple arguments and partial application of such functions without writing many parentheses in either the type or the program.Can you give examples of programs foo, bar and baz, such that one might expect foo bar baz to be well-typed if function application were to associate in the opposite direction, but such
that foo bar baz is in reality ill-typed?
-- For example,
foo :: Bool -> Bool
foo = not
bar :: Bool -> Bool
bar = not
baz :: Bool
baz = True
-- Then foo (bar baz) is well-typed at type Bool
-- However, as function application associates to the left in reality and not to the right, foo bar baz should be parsed as (not not) True, which does not type check.2 Currying inClass
Please implement two functions
curry :: ((a, b) -> c) -> (a -> b -> c)
uncurry :: (a -> b -> c) -> ((a, b) -> c)curry f a b = f (a, b)
uncurry g (a, b) = g a bCan you convince yourself that curry and uncurry are mutually inverse? Try it out on some example functions!
Please simplify the types of curry and uncurry by removing unnecessary parentheses
curry :: ((a, b) -> c) -> a -> b -> c
uncurry :: (a -> b -> c) -> (a, b) -> c3 Filter atHome
The function filter can be defined in terms of concat and map:
filter p = concat . map box
where box x = _Complete the definition of box.
box x = if p x then [x] else []4 Function Composition atHome
Function composition first applies the latter of the supplied
functions to the argument, the former thereafter. Write a function
before that can be used to rewrite f . g . h to h `before` g `before` f. What can you say about associativity of (.) and
before?
before :: (a -> b) -> (b -> c) -> (a -> c)
before = flip (.)
-- both (.) and before are associative operations5 Higher order data types atHome challenging
We have seen that [...] is a type function that maps types to
types. Similarly because −> is a type constructor mapping two types
to a type, for some c also c −> is a type function mapping a type
a to c −> a. Rewrite the type of map by substituting the type
function [...] by c −>. Can you derive an implementation from the
resulting type?
mapFun :: (a -> b) -> (c -> a) -> (c -> b)
mapFun = (.)