Haskell High Order Functions, Function Declaration - function

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' (,).

Related

Haskell function definition, missing argument? [duplicate]

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.

Inferring function type from function definition Haskell

So I was taking a test about Haskell and one question said:
let the function be
lolo g x = ys
where ys = [x] ++ filter (curry g x) ys
then determine the type of the function called lolo. The options are:
a) (a,b) -> Bool -> b -> [(a,b)]
b) (b -> b -> b) -> Bool -> [b]
c) ((b,b) -> Bool) -> b -> [b]
d) (a -> b -> Bool) -> b -> [c]
Can somebody please explain which one it is and why? I'm really confused about this one... things I do not understand are:
1) the curry function can only be applied to functions right? not datatypes that may be tuples? then you can infer that g is a function in this context? what if g and x are both functions? is it possible to use curry with nth arguments? I've only seen curry used with 1 argument.
2) the other thing I don't understand very much is the recursion in the definition of ys. so ys is defined by ys, but I don't see the base case in this scenario. Will it ever end? maybe it's the filter function that makes the recursion end.
3) also in curry g x = curry (g x) right? (this is a question about precedence in application of functions)
Thanks a lot
1) The first argument to curry has to be a function, it is what is known as a higher order function, it takes a function and returns a new one. While its type is printed out in GHCi as
curry :: ((a, b) -> c) -> a -> b -> c
It is more clearly represented (IMO) as
curry :: ((a, b) -> c) -> (a -> b -> c)
Which makes it more obvious that it takes a function and returns a new function. Technically, you could say that curry takes 3 arguments, one of type (a, b) -> c, one of type a, and one of type b. It just takes a function that normally accepts a tuple of arguments and converts it into a function that takes 2 arguments.
2) The computation for ys will never end, don't bother trying to call length on it, you'll just run the computation forever. This isn't a problem, though, you can work with infinite lists and non-terminating lists just fine (non-terminating being a list where it takes forever to compute the next element, not just one that has infinite elements). You can still use functions like take and drop on it, though.
3) Does curry g x == curry (g x)? No! When you see an expression like a b c d e, all of b, c, d, and e are arguments to a. If you instead saw a b c (d e), then e is applied to d, and that result is applied to a b c. Consider filter even [1..10], this is certainly not the same as filter (even [1..10]), since it wouldn't even compile! (even :: Integral a => a -> Bool).
When solving this sort of problem, first look at what functions are used in the expression that you already know the types of:
(++) :: [a] -> [a] -> [a]
filter :: (b -> Bool) -> [b] -> [b]
curry :: ((c, d) -> e) -> c -> d -> e
I've used different type variables in each so that there will be less confusion when trying to line up the types. You can get these types by loading up GHCi, then typing
> :type (++)
(++) :: [a] -> [a] -> [a]
> -- Or just use :t
> :t filter
filter :: (a -> Bool) -> [a] -> [a]
> :t curry
curry :: ((a, b) -> c) -> a -> b -> c
As you can see, I've changed filter to use b instead of a, and curry to use c, d, and e. This doesn't change the meaning any more than f x = x + 1 versus f y = y + 1, it'll just make it easier to talk about.
Now that we've broken down our function into its subcomponents, we can work from the "top" down. By top, I mean the last function that gets called, namely (++). You can picture this function by a tree like
(++)
/ \
[x] filter
/ \
curry ys
/ \
g x
So we can clearly see that (++) is at the top. Using that, we can infer that [x] has the type [a], which means that x ~ a (the tilde is the type equality symbol) and consequently ys ~ [a], since ys = [x] ++ something. Now that we know the type of x, we can start filling out the rest of the expression. Next, we work down to filter (curry g x) ys. Since it is the second argument to (++), we can infer that this subexpression also has the type [a]. If we look at the type of filter:
filter :: (b -> Bool) -> [b] -> [b]
The final result is a list of type [b]. Since it's being applied to [x] ++, we can infer that filter (curry g x) ys :: [a]. This means that [b] ~ [a] => b ~ a. For reference, this makes filter's type
filter :: (a -> Bool) -> [a] -> [a]
This now places a constraint on curry g x, it must fit into filter's first argument which has the type a -> Bool. Looking at curry's type again:
curry :: ((c, d) -> e) -> c -> d -> e
This means that e ~ Bool, and d ~ a. If we plug those back in
curry :: ((c, a) -> Bool) -> c -> a -> Bool
Ignoring g for now, we look at the type of x, which we figured out is a. Since x is the second argument to curry, that means that x matches with the argument of type c, implying that c ~ a. Substituting this into what we just computed we get
curry :: ((a, a) -> Bool) -> a -> a -> Bool
With
curry g x :: a -> Bool
filter (curry g x) :: [a] -> [a]
filter (curry g x) ys :: [a]
[x] ++ filter (curry g x) ys :: [a]
From this we can directly infer that lolo's type signature ends with [a], so
lolo :: ??? -> [a]
I'll leave you to do the remaining few steps to figure out what ??? is.

Is there a name for this function or pattern?

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

difference between (a -> a) and a -> a

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.

Using an element against an entire list in Haskell

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?