This question already has answers here:
Haskell recursive function example with foldr
(2 answers)
Closed 6 years ago.
module Tf0 where
all' :: (a -> Bool) -> [a] -> Bool
all' p = foldr (&&) True . map p
main :: IO()
xs = [1,3,5,7,9]
xs1 = [1,3,11,4,15]
k1 = all' (<10) xs
k2 = all' (<10) xs1
k3 = all' (<10)
main = print k1
Questions:
In the function definition (all' p = foldr (&&) True . map p) there is no list as an input while the function Type shows a list as an input ([a]), yet trying to check the function (see bellow k1, k2, k3) shows that a list is needed.
How can the function be defined without the list?
One of the fundamental aspects of Haskell is that conceptually a function always takes one argument. Indeed take for instance the function (+):
(+) :: Int -> Int -> Int
(technically it is (+) :: Num a => a -> a -> a, but let us keep things simple).
Now you can argue that (+) takes two arguments, but conceptually it takes one argument. Indeed: the signature is in fact
(+) :: Int -> (Int -> Int)
So you feed it one integer and now it returns a function, for instance:
(+) 5 :: Int -> Int
So you have, by giving it a 5, constructed a function that will add 5 to a given operand (again a function that takes one argument).
Now applying this to your question, the signature of all' is in fact:
all' :: (a -> Bool) -> ([a] -> Bool)
So if you apply all' with one argument, it returns a function that maps a list [a] to a Bool. Say for the sake of argument that we set p to \_ -> True, then we return:
foldr (&&) True . map (\_ -> True) :: [a] -> Bool
so indeed a function that takes a list [a] and maps it on a Bool. In a next phase you apply a list to that (returning) function.
In other words, functional programming can be seen as a long chain of specializing a function further and further until it is fully grounded and can be evaluated.
Haskell only provides this in an elegant way such that you do not have to think about functions generating functions. But conceptually, this happens all the time. Given you want to implement a function f :: a -> b -> c, you can do this like:
f x y = g (x+1) y
(with g :: a -> b -> c), but you can also decide to leave a parameter out, and define it as:
f x = g (x+1)
since g (x+1) will return a function that can apply with the y eventually.
Related
I am studying for an exam and I'm confused at this function. Based on the output how do I know that the type declaration of the function is (a -> b -> c)? also, how I can evaluate my function?
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
What I understand is that high order functions in haskell mean that they take a function as a parameter and return a function as well, right? how can I call this particular function?
I did this:
zipWith' [1..5] ['a','z','r']
but I know is wrong because I am calling it as if it were the regular zip function that takes 2 lists and returns a tuple. I am just confused at the type declaration
zipWith' :: [a] -> [b] -> [(a,b)]
For this answer, we'll acknowledge that all functions are curried. That is, every function has a type a -> b, where a and b are some type.
A higher-order function is one whose type includes a function for either its argument or return type. Return values are easy: it's any function you ordinary think of as taking more than one argument:
take :: Int -> [a] -> [a]. It takes an Int and returns a (polymorphic) function that takes a list and returns a list.
map :: (a -> b) -> [a] -> [b]. It takes a function (literally any function) and returns a function from lists to lists. The types of the return value is determined by the type of the argument.
Higher-order functions that take an function and return something that isn't a function are actually somewhat rare. Perhaps a commenter will point out an obvious one I am overlooking, but until then, consider fix :: (a -> a) -> a.
Now, zipWith' is an example of a higher-order function whose argument itself must be a higher-order function. The general type a -> b can unify with an ordinary function like ord :: Char -> Int (a ~ Char and b ~ Int) as well as a higher-order function like (+) (with a ~ Num t => t and b ~ Num t => t -> t. The type a -> b -> c will only unify with higher-order functions. a may or may not be a function type, but b -> c is an explicit function type.
This means that once you apply zipWith' to some higher-order function, type inference gives you more information about what the types of [a], [b], and [c] must be in the resulting function.
zipWith' (+) tells you that a ~ b ~ c ~ Num t => [t].
zipWith' (,) tells you that a and b are still unrestricted, but c ~ (a, b)
zipWith' (:) tells you that a is unrestricted, but b ~ c ~ [a].
It may also help if you consider that zip :: [a] -> [b] -> [(a,b)] could be defined as zip = zipWith' (,).
Instead of fmap, which applies a function to a value-in-a-functor:
fmap :: Functor f => (a -> b) -> f a -> f b
I needed a function where the functor has a function and the value is plain:
thing :: Functor f => f (a -> b) -> a -> f b
but I can't find one.
What is this pattern called, where I apply a function-in-a-functor (or in an applicative, or in a monad) to a plain value?
I've implemented it already, I just don't quite understand what I did and why there wasn't already such a function in the standard libraries.
You don't need Applicative for this; Functor will do just fine:
apply f x = fmap ($ x) f
-- or, expanded:
apply f x = fmap (\f' -> f' x) f
Interestingly, apply is actually a generalisation of flip; lambdabot replaces flip with this definition as one of its generalisations of standard Haskell, so that's a possible name, although a confusing one.
By the way, it's often worth trying Hayoo (which searches the entirety of Hackage, unlike Hoogle) to see what names a function is often given, and whether it's in any generic package. Searching for f (a -> b) -> a -> f b, it finds flip (in Data.Functor.Syntax, from the functors package) and ($#) (from the synthesizer package) as possible names. Still, I'd probably just use fmap ($ arg) f at the use site.
As Niklas says, this is application in some applicative functor to a lifted value.
\f a -> f <*> pure a
:: Applicative f => f (a -> b) -> a -> f b
or more generally (?), using Category (.)
\f a -> f . pure a
:: (Applicative (cat a), Category cat) => cat b c -> b -> cat a c
I've noticed that (although I was once told that (a -> a) and a -> a meant the same thing), I get error messages when I use the (a -> a). Should I only use (a -> a) when using brackets amongst the types? (i.e. (5 + 3) instead of 5 + 3)? Just not quite certain of when it's necessary
(a -> a) and a -> a are the same alone,
ff :: (a -> a) -- this compiles
ff = id
gg :: a -> a
gg = id
h :: a -> a -> Bool
h _ _ = True
i = h ff gg -- this compiles => ff & gg are of the same type.
but will be different when combined with more types like:
a -> a -> b
(a -> a) -> b
This is because -> is right-associative, so a -> a -> b actually means a -> (a -> b) (take an a and return a function), which is different from (a -> a) -> b (take a function and return a b).
This is like (1+2)*3 is different from 1+2*3.
Parenthesization disambiguates several constructs in Haskell, when other information available to the compiler doesn't help:
Application associates to the left
so you can omit parens on function arguments.
Expressions involving infix operators are disambiguated by the operator's fixity.
so no need for parens in many cases with binary operators of different fixity.
Consecutive unparenthesized operators with the same precedence must both be either left or right associative to avoid a syntax error.
and finally:
Given an unparenthesized expression x op y op z, parentheses must be added around either x op y or y op z, unless certain conditions about precendence hold
My general advice, if the above statements don't make any sense: over-parenthesize things, until you learn the rules. Or, study the Haskell Report very hard.
Consider the expression 10 / 2 / 5. Is that the same as (10 / 2) / 5 or 10 / (2 / 5)? If you interpret / to be mathematical division, then the former is true, while the latter is false. So you see, the answer to your question is "there is a difference, but only sometimes".
Types are the opposite. a -> b -> c is the same as a -> (b -> c), and definitely not the same as (a -> b) -> c.
You say you're not quite sure when it's necessary: well here it is. When the argument to your function is also a function, then it is necessary.
Consider map :: (a -> b) -> [a] -> [b]. This is different than a -> b -> [a] -> [b], for you see, (a -> b) indicates a specific kind of function: a function from type a to type b.
iterate :: (a -> a) -> a -> [a] is more interesting. This function requires that the input and output types of the function in the first parameter must be the same.
You may be interested in reading up on currying and partial application. One good resource among many: Learn you a Haskell # Curried Functions
This only makes a difference when you're making higher order functions. For example:
f :: a -> a -> b
is a function that expects two arguments of type a and return a value of type b, like so
f 2 2
f True True
But the function
f :: (a -> a) -> b
Expects a function as an argument. The only time where a -> a and (a -> a) are the same if they're the only argument in type inference, like here
f :: (a -> a)
-- Same type as
f :: a -> a
The rules for () in typing are pretty much the same as in normal expressions. It's like expressions a level above.
They are the same. Could you describe the errors you get when you use (a -> a)? It works fine for me with ghci-7.0.3:
Prelude> let f :: (a -> a); f = id
Prelude> f "foo"
"foo"
Prelude>
In general, you need to use parentheses in types when you're using functions as arguments. For example, map :: (a -> b) -> [a] -> [b]. Without the parens, it would mean something else.
This question is related to this Function Composition VS Function Application which answered by antal s-z.
How you can get this ?
map has type (a -> b) -> [a] -> [b]
head has type [a] -> a
map head has type [[a]] -> [a]
Why the following code has type error for function composition ?
test :: [Char] -> Bool
test xs = not . null xs
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames = map head . filter (\mn -> not . null mn) middleNames
but this does not have type error
getFirstElements :: [[a]] -> [a]
getFirstElements = map head . filter (not . null)
Is it a must to write a point free function in order to utilize the function composition ?
I still not very understand the usage of function composition.
Please help.
Thanks.
That's just because function application x y has higher precedence than composition x . y
test :: [Char] -> Bool
test xs = (not . null) xs
-- # ^ ^
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames = (map head . filter (\mn -> (not . null) mn)) middleNames
-- # ^ ^ ^ ^
Your error here is actually really simple. If you remember the last part of my answer to your last question, the . operator has higher precedence than anything except for function application. Thus, consider your example of
test :: [Char] -> Bool
test xs = not . null xs
This is parsed as test xs = not . (null xs). Of course, null xs has type Bool, and you can't compose a boolean, and so you get a type error. Thus, you could make your examples work like so:
test :: [Char] -> Bool
test xs = (not . null) xs
getMiddleInitials :: [String] -> [Char]
getMiddleInitials middleNames =
(map head . filter (\mn -> (not . null) mn)) middleNames
Of course, writing it this way is unusual, but it would work fine.
And no, there are other uses of function composition besides point-free style. One example is to use function composition for some things (e.g. the argument to map or filter), but specify the rest. For instance, take this contrived example:
rejectMapping :: (a -> Bool) -> (a -> b) -> [a] -> [b]
rejectMapping p f = map f . filter (not . p)
This is partly point-free (not . p, for instance, and we left off the final argument), but partly point-full (the existence of p and f).
I have an assignment and am currently caught in one section of what I'm trying to do. Without going in to specific detail here is the basic layout:
I'm given a data element, f, that holds four different types inside (each with their own purpose):
data F = F Float Int, Int
a function:
func :: F -> F-> Q
Which takes two data elements and (by simple calculations) returns a type that is now an updated version of one of the types in the first f.
I now have an entire list of these elements and need to run the given function using one data element and return the type's value (not the data element). My first analysis was to use a foldl function:
myfunc :: F -> [F] -> Q
myfunc y [] = func y y -- func deals with the same data element calls
myfunc y (x:xs) = foldl func y (x:xs)
however I keep getting the same error:
"Couldn't match expected type 'F' against inferred type 'Q'.
In the first argument of 'foldl', namely 'myfunc'
In the expression: foldl func y (x:xs)
I apologise for such an abstract analysis on my problem but could anyone give me an idea as to what I should do? Should I even use a fold function or is there recursion I'm not thinking about?
The type of foldl is
foldl :: (a -> b -> a) -> a -> [b] -> a
but the type of func is
-- # a -> b -> a
func :: F -> F -> Q
The type variable a cannot be simultaneously F and Q, thus the error.
If the Q can be converted to and from F, you could use
myfunc y xs = foldl (func . fromQ) (toQ y) xs
where
func . fromQ :: Q -> F -> Q
toQ y :: Q
xs :: [F]
so this satisfies all the type requirements, and will return the final Q.
maybe you need map?
map :: (f -> q) -> [f] -> [q]
it evaluates a function on each element in a list and gives a list of the results. I'm not sure why your function takes two Fs though, possibly to work with foldl?