Haskell - Filter, Currying - haskell

I just want to know if my following understanding about currying functions is correct.
I want to filter all elements from a list which are > 4. I can achieve this like so:
filter (>4) [1..10]
(>) is defined as Ord a => a -> a -> Bool, thats why it cant be bassed to filter.
(>4) is defined as (Ord a, Num a) => a -> Bool. The function (>) is now curried and still expects one parameter.
Because of 2., (>4) can be passed to filter.
Every List-Element, which is passed to filter, will be passed to (>4) and and filter will validate the predicate and return the result.
Is this correct?

The reasoning is more or less correct. (>) is a function with signature:
(>) :: Ord a => a -> (a -> Bool)
so it is a function that (like any other function in Haskell) takes one parameter, and here returns a function a -> Bool.
The problem is thus that if we would use filter (>) [1,4,2,5], then we would make a call (>) 1, and this would thus return a function a -> Bool, but a filter can not work with that, it requires a function that takes an element from the list, and returns a Bool, not a function that returns a function that maps to a Bool.
We thus can for example use:
filter ((<) 4) [1,4,2,5]
Here we thus perform partial application [Haskell-wiki] of the function. This thus means that we generate a function (<) 4 :: (Num a, Ord a) => a -> Bool. We thus can filter with that function, it will thus return [5].
We can also make a function with a lambda expression to "swap" the order of the parameters:
filter (\x -> (>) x 4) [1,4,2,5]
Here for a value x, we will thus call ((>) x) 4, and this will thus return a Bool.
Since it happens often that one of the two sides of an infix operator is provided a value, Haskell has sectioning syntax for an infix operator [Haskell-wiki]:
(2^) (left section) is equivalent to (^) 2, or more verbosely \x -> 2 ^ x;
(^2) (right section) is equivalent to flip (^) 2, or more verbosely \x -> x ^ 2
So we can rewrite the last expression to:
filter (> 4) [1,4,2,5]

Related

Meaning of `$` when used as argument to map

I understand that the $ operator is for avoiding parentheses. Anything appearing after it will take precedence over anything that comes before.
I am trying to understand what it means in this context:
map ($ 3) [(+),(-),(/),(*)]
With the following code:
instance Show (a -> b) where
show a = function
main = putStrLn $ show $ map ($ 3) [(+),(-),(/),(*)]
The output is
["function", "function", "function", "function"]
This doesn't help me understand the meaning of the $ here.
How can I display more helpful output?
($) :: (a -> b) -> a -> b is a function that takes a function as first parameter, and a value as second and returns the value applied to that function.
For example:
Prelude> (1+) $ 2
3
The expression ($ 3) is an example of infix operator sectioning [Haskell-wiki]. ($ 3) is short for \f -> f $ 3, or simpler \f -> f 3. It thus is a function that takes a function and applies 3 to that function.
For your expression:
map ($ 3) [(+),(-),(/),(*)]
the output is thus equivalent to:
[(3+), (3-), (3/), (3*)] :: Fractional a => [a -> a]
Since (+), (-), (*) :: Num a => a -> a -> a work with types that are members of the Num typeclass, and (/) :: Fractional a => a -> a -> a works with types that are members of the Fractional type class, and all Fractional types are num types as well, 3 is here a Fractional type, and the list thus contains functions that are all of the type a -> a with a a member of Fractional.
How can I display more helpful output?
The compiler does not keep track of the expressions, as specified in the Haskell wiki page on Show instance for functions [Haskell-wiki].
The Haskell compiler doesn't maintain the expressions as they are, but translates them to machine code or some other low-level representation. The function \x -> x - x + x :: Int -> Int might have been optimized to \x -> x :: Int -> Int. If it's used anywhere, it might have been inlined and optimized to nothing. The variable name x is not stored anywhere. (...)
So we can not "look inside" the function and derive an expression that is human-readable.

Variable scope in a higher-order lambda function

In working through a solution to the 8 Queens problem, a person used the following line of code:
sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs
try is an an item; qs is a list of the same items.
Can someone explain how colDist and q in the lambda function get bound to anything?
How did try and q used in the body of lambda function find their way into the same scope?
To the degree this is a Haskell idiom, what problem does this design approach help solve?
The function any is a higher-order function that takes 2 arguments:
the 1st argument is of type a -> Bool, i.e. a function from a to Bool
the 2nd argument is of type [a], i.e. a list of items of type a;
i.e. the 1st argument is a function that takes any element from the list passed as the 2nd argument, and returns a Bool based on that element. (well it can take any values of type a, not just the ones in that list, but it's quite obviously certain that any won't be invoking it with some arbitrary values of a but the ones from the list.)
You can then simplify thinking about the original snippet by doing a slight refactoring:
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f = (\(colDist, q) -> abs (try - q) == colDist)
which can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f (colDist, q) = abs (try - q) == colDist)
which in turn can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f pair = abs (try - q) == colDist) where (colDist, q) = pair
(Note that sameDiag could also have a more general type Integral a => a -> [a] -> Bool rather than the current monomorphic one)
— so how does the pair in f pair = ... get bound to a value? well, simple: it's just a function; whoever calls it must pass along a value for the pair argument. — when calling any with the first argument set to f, it's the invocation of the function any who's doing the calling of f, with individual elements of the list xs passed in as values of the argument pair.
and, since the contents of xs is a list of pairs, it's OK to pass an individual pair from this list to f as f expects it to be just that.
EDIT: a further explanation of any to address the asker's comment:
Is this a fair synthesis? This approach to designing a higher-order function allows the invoking code to change how f behaves AND invoke the higher-order function with a list that requires additional processing prior to being used to invoke f for every element in the list. Encapsulating the list processing (in this case with zip) seems the right thing to do, but is the intent of this additional processing really clear in the original one-liner above?
There's really no additional processing done by any prior to invoking f. There is just very minimalistic bookkeeping in addition to simply iterating through the passed in list xs: invoking f on the elements during the iteration, and immediately breaking the iteration and returning True the first time f returns True for any list element.
Most of the behavior of any is "implicit" though in that it's taken care of by Haskell's lazy evaluation, basic language semantics as well as existing functions, which any is composed of (well at least my version of it below, any' — I haven't taken a look at the built-in Prelude version of any yet but I'm sure it's not much different; just probably more heavily optimised).
In fact, any is simple it's almost trivial to re-implement it with a one liner on a GHCi prompt:
Prelude> let any' f xs = or (map f xs)
let's see now what GHC computes as its type:
Prelude> :t any'
any' :: (a -> Bool) -> [a] -> Bool
— same as the built-in any. So let's give it some trial runs:
Prelude> any' odd [1, 2, 3] -- any odd values in the list?
True
Prelude> any' even [1, 3] -- any even ones?
False
Prelude> let adult = (>=18)
Prelude> any' adult [17, 17, 16, 15, 17, 18]
— see how you can sometimes write code that almost looks like English with higher-order functions?
zip :: [a] -> [b] -> [(a,b)] takes two lists and joins them into pairs, dropping any remaining at the end.
any :: (a -> Bool) -> [a] -> Bool takes a function and a list of as and then returns True if any of the values returned true or not.
So colDist and q are the first and second elements of the pairs in the list made by zip [1..] qs, and they are bound when they are applied to the pair by any.
q is only bound within the body of the lambda function - this is the same as with lambda calculus. Since try was bound before in the function definition, it is still available in this inner scope. If you think of lambda calculus, the term \x.\y.x+y makes sense, despite the x and the y being bound at different times.
As for the design approach, this approach is much cleaner than trying to iterate or recurse through the list manually. It seems quite clear in its intentions to me (with respect to the larger codebase it comes from).

Haskell recursive function example with foldr

I've taken up learning Haskell again, after a short hiatus and I am currently trying to get a better understanding of how recursion and lambda expressions work in Haskell.
In this: YouTube video, there is a function example that puzzles me far more than it probably should, in terms of how it actually works:
firstThat :: (a -> Bool) -> a -> [a] -> a
firstThat f = foldr (\x acc -> if f x then x else acc)
For the sake of clarity and since it wasn't immediately obvious to me, I'll give an example of applying this function to some arguments:
firstThat (>10) 2000 [10,20,30,40] --returns 20, but would return 2000, if none of the values in the list were greater than 10
Please correct me, if my assumptions are wrong.
It seems firstThat takes three arguments:
a function that takes one arguments and returns a Boolean value. Since the > operator is actually an infix function, the first argument in the example above seems the result of a partial application to the > function – is this correct?
an unspecified value of the same type expected as the missing argument to the function provided as the first argument
a list of values of the aforementioned type
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening. The lambda expression provided as an argument to foldr seem to be missing its arguments too.
So, how exactly does this function work? I apologize if I am being too dense or fail to see the forest for the trees, but I just cannot wrap my head around it, which is frustrating.
Any helpful explanation or example(s) would be greatly appreciated.
Thanks!
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening.
You are right. However, there is a nicer way of putting it than talking about "missing arguments" -- one that doesn't lead you into asking where they have gone. Here are two ways in which the arguments are not missing.
Firstly, consider this function:
add :: Num a => a -> a -> a
add x y = x + y
As you may know, we can also define it like this:
add :: Num a => a -> a -> a
add = (+)
That works because Haskell functions are values like any other. We can simply define a value, add, as being equal to another value, (+), which just happens to be a function. There is no special syntax required to declare a function. The upshot is that writing arguments explicitly is (almost) never necessary; the main reason why we do so because it often makes code more readable (for instance, I could define firstThat without writing the f parameter explicitly, but I won't do so because the result is rather hideous).
Secondly, whenever you see a function type with three arguments...
firstThat :: (a -> Bool) -> a -> [a] -> a
... you can also read it like this...
firstThat :: (a -> Bool) -> (a -> [a] -> a)
... that is, a function of one argument that produces a function of two arguments. That works for all functions of more than one argument. The key takeaway is that, at heart, all Haskell functions take just one argument. That is why partial application works. So on seeing...
firstThat :: (a -> Bool) -> a -> [a] -> a
firstThat f = foldr (\x acc -> if f x then x else acc)
... you can accurately say that you have written explicitly all parameters that firstThat takes -- that is, only one :)
The lambda expression provided as an argument to foldr seem to be missing its arguments too.
Not really. foldr (when restricted to lists) is...
foldr :: (a -> b -> b) -> b -> [a] -> b
... and so the function passed to it takes two arguments (feel free to add air quotes around "two", given the discussion above). The lambda was written as...
\x acc -> if f x then x else acc
... with two explicit arguments, x and acc.
a function that takes one arguments and returns a Boolean value. Since the > operator is actually an infix function, the first argument in the example above seems the result of a partial application to the > function – is this correct?
yes: (>10) is short for \x -> x > 10, just as (10>) would be short for \x -> 10 > x.
an unspecified value of the same type expected as the missing argument to the function provided as the first argument
first of all, it's not a missing argument: by omitting an argument, you obtain a function value. however, the type of the 2nd argument does indeed match the argument of the function >10, just as it matches the type of the elements of the list [10,20,30,40] (which is better reasoning).
a list of values of the aforementioned type
yes.
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening. The lambda expression provided as an argument to foldr seem to be missing its arguments too.
that's because given e.g. foo x y z = x * y * z, these 2 lines are equivalent:
bar x = foo x
bar x y z = foo x y z
— that's because of a concept called currying. Currying is also the reason why function type signatures are not (a, b) -> c but instead a -> b -> c, which in turn is equivalent to a -> (b -> c) because of the right associativity of the -> type operator.
Therefore, these two lines are equivalent:
firstThat f = foldr (\x acc -> if f x then x else acc)
firstThat f x y = foldr (\x acc -> if f x then x else acc) x y
Note: that you can also use Data.List.find combined with Data.Maybe.fromMaybe:
λ> fromMaybe 2000 $ find (>10) [10, 20, 30]
20
λ> fromMaybe 2000 $ find (>10) [1, 2, 3]
2000
See also:
https://en.wikipedia.org/wiki/Currying.
https://www.fpcomplete.com/user/EFulmer/currying-and-partial-application
http://learnyouahaskell.com/higher-order-functions

Why is the use of (>100) partial application?

This code illustrates the use of partial application through the use of an operator section :
gt100 :: Integer -> Bool
gt100 x = x > 100
greaterThan100 :: [Integer] -> [Integer]
greaterThan100 xs = filter gt100 xs
greaterThan100_2 :: [Integer] -> [Integer]
greaterThan100_2 xs = filter (\x -> x > 100) xs
greaterThan100_3 :: [Integer] -> [Integer]
greaterThan100_3 xs = filter (>100) xs
The operator section (>100) partially applies the operator to one
of its two arguments. So the operator in this case is >
Why is this partial application as the > operator is being applied
to the entire Integer list ?
How is this different from lambda expression (\x -> x > 100) which
apparently is not partial application ?
Taken from http://www.seas.upenn.edu/~cis194/spring13/lectures/04-higher-order.html
Update :
Thanks to answers this appears clearer.
So here now is my understanding :
*Main> :t (>)
(>) :: Ord a => a -> a -> Bool
Is not applied at all as it accepts two parameters "a -> a" but they are not applied.
*Main> :t (>100)
(>100) :: (Ord a, Num a) => a -> Bool
Is partially applied as a function of type "a -> Bool" is created
*Main> :t (3>100)
(3>100) :: Bool
Is evaluated to type Bool which is the return type of operator (>) as illustrated by :t (>)
Why is this partial application as the > operator is being applied to the entire Integer list ?
It is not applied to the entire list, as a whole, but to the individual elements, one by one. When the > is partially applied over 100, it creates a new function.
Prelude> :type (> 100)
(> 100) :: (Num a, Ord a) => a -> Bool
Now, the function accepts an argument and returns Bool. This function is applied to all the elements in the list by the filter function.
How is this different from lambda expression (\x -> x > 100) which apparently is not partial application ?
> is a function which needs two operands to operate. You are already passing one of them, as 100. To completely execute the function, you need one more argument. So, the function > is partially applied with 100.
In the second case, you are creating a new function which needs only one argument to execute. Once you pass that argument, your function will be executed. So, the lambda function is not applied partially.
How is this [(<) 100] different from lambda expression (\x -> (<) 100 x) which apparently is not partial application? [1]
I think it is important to draw a distinction between semantic properties and syntactic properties. The two terms you suggested are semantically identical -- that is, there is no Haskell function you can write that reduces to one thing when applied to (<) 100 and reduces to a different thing when applied to (\x -> (<) 100 x).
However, partial application is a syntactic property -- that is, it is a property not of the behavior of a term but of the particular implementation chosen. (In analogous terms to my definition of a semantic property, a syntactic property is about whether you could write a Haskell function that reduces to one thing when applied to the string "(<) 100" and reduces to a different thing when applied to the string "(\x -> (<) 100 x)", which is eminently possible.) If I had to define it, I would define it this way: partial application is an application term with an arrow type. [2] Both of your terms are well-typed and have arrow types. But (<) 100 is an application term, whereas \x -> (<) 100 x is a lambda term (that has an application in its body).
As for operator sections like (100<) and (>100), it is not immediately obvious what to do with these. One choice is to simply decree that all operator sections are partial applications (or to simply decree that no operator sections are partial applications, of course). Another is to treat them as shorthand for (<) 100 and flip (>) 100, respectively, in which case we would still consider them partial applications (since they are application terms and have arrow types). [3] Yet a third is to treat them as shorthand for \x -> (<) 100 x and \x -> (>) x 100, respectively, in which case one might claim they are not partial applications.
But the distinction is, in my opinion, not too important: generally, semantic properties are more interesting and useful than merely syntactic ones.
[1] To avoid muddying the waters, I have used (<) 100 instead of (>100). We will discuss this distinction shortly.
[2] There is some question about what to do if the type is polymorphic. Let's punt on that question for now.
[3] This differs from simply decreeing that all operator sections are partial applications; consider some one-argument operator (!) and its section (100!), which we would then be treating as shorthand for (!) 100. This is an application term, but does not have an arrow in its type.

Understanding Haskell Type Signatures

I am in the process of teaching myself Haskell and I was wondering about the following type signatures:
Prelude> :t ($)
($) :: (a -> b) -> a -> b
Prelude>
How should I interpret (no pun intended) that?
A semi-similar result is also proving to be puzzling:
Prelude> :t map
map :: (a -> b) -> [a] -> [b]
Prelude>
I'll start with map. The map function applies an operation to every element in a list. If I had
add3 :: Int -> Int
add3 x = x + 3
Then I could apply this to a whole list of Ints using map:
> map add3 [1, 2, 3, 4]
[4, 5, 6, 7]
So if you look at the type signature
map :: (a -> b) -> [a] -> [b]
You'll see that the first argument is (a -> b), which is just a function that takes an a and returns a b. The second argument is [a], which is a list of values of type a, and the return type [b], a list of values of type b. So in plain english, the map function applies a function to each element in a list of values, then returns the those values as a list.
This is what makes map a higher order function, it takes a function as an argument and does stuff with it. Another way to look at map is to add some parentheses to the type signature to make it
map :: (a -> b) -> ([a] -> [b])
So you can also think of it as a function that transforms a function from a to b into a function from [a] to [b].
The function ($) has the type
($) :: (a -> b) -> a -> b
And is used like
> add3 $ 1 + 1
5
All it does is take what's to the right, in this case 1 + 1, and passes it to the function on the left, here add3. Why is this important? It has a handy fixity, or operator precedence, that makes it equivalent to
> add3 (1 + 1)
So whatever to the right gets essentially wrapped in parentheses before being passed to the left. This just makes it useful for chaining several functions together:
> add3 $ add3 $ add3 $ add3 $ 1 + 1
is nicer than
> add3 (add3 (add3 (add3 (1 + 1))))
because you don't have to close parentheses.
Well, as said already, $ can be easily understood if you just forget about currying and see it like, say, in C++
template<typename A, typename B>
B dollar(std::function<B(A)> f, A x) {
return f(x);
}
But actually, there is more to this than just applying a function to a value! The apparent similarity between the signatures of $ and map has in fact a pretty deep category-theory meaning: both are examples of the morphism-action of a functor!
In the category Hask that we work with all the time, objects are types. (That is a bit confusionsome, but don't worry). The morphisms are functions.
The most well-known (endo-)functors are those which have an instance of the eponymous type class. But actually, mathematically, a functor is only something that maps both objects to objects and morphisms to morphisms1. map (pun intended, I suppose!) is an example: it takes an object (i.e. type) A and maps it to a type [A]. And, for any two types A and B, it takes a morphism (i.e. function) A -> B, and maps it to the corresponding list-function of type [A] -> [B].
This is just a special case of the functor class signature operation:
fmap :: Functor f => (a->b) -> (f a->f b)
Mathematics doesn't require this fmap to have a name though. And so there can be also the identity functor, which simply assigns any type to itself. And, every morphism to itself:
($) :: (a->b) -> (a->b)
"Identity" exists obviously more generally, you can also map values of any type to themselves.
id :: a -> a
id x = x
And sure enough, a possible implementation is then
($) = id
1Mind, not anything that maps objects and morphisms is a functor... it does need to satisfy the functor laws.
($) is just function application. It gets a function of type a->b, an argument of type a, applies the function and returns a value of type b.
map is a wonderful example for how reading a function type signature helps understanding it. map's first argument is a function that takes a and returns b, and its second argument is a list of type [a].
So map applies a function of type a->b to a list of a values. And the result type is indeed of type [b] - a list of b values!
(a->b)->[a]->[b] can be interpreted as "Accepts a function and a list and returns another list", and also as "Accepts a function of type a->b and returns another function of type [a]->[b]".
When you look at it this way, map "upgrade" f (the term "lift" is often used in this context) to work on lists: if double is a function that doubles an integer, then map double is a function that double every integer in a list.

Resources