The first argument, that fmap is expected is a function with one argument.
fmap :: Functor f => (a -> b) -> f a -> f b
Then I tried as follow in prelude:
Prelude> x = fmap (\x y -> x * y)
As you can see, the first argument to fmap is a function, that has two arguments. Why does the compiler let it pass?
The function that I pass to fmap above has two arguments not one!
Haskell does not actually have functions with more (or less) than one argument. A "two-argument function" is really just a function that takes one argument and produces another function that takes another argument. That is, \x y -> x * y is just a syntactic short cut for \x -> \y -> x * y. This concept is known as currying.
So this should explain what's happening in your example. Your fmap will simply turn an f of numbers into an f of functions. So, for example, x [1,2,3] would produce the list [\y -> 1 * y, \y -> 2 * y, \y -> 3 * y] (a.k.a. [(1*), (2*), (3*)]).
You have defined a function. One of the fundamental aspects of functional programming that functions can be parameters, stored into variables, etc.
If we then query the type of x, we get:
Prelude> :t x
x :: (Functor f, Num a) => f a -> f (a -> a)
So x is now a function that takes as input a Functor with a applied on that function, and returns the an element of a type with the same functor, but applied with a -> a.
So you can for instance apply a list on x, like:
Prelude> :t x [1,4,2,5]
x [1,4,2,5] :: Num a => [a -> a]
So now we have a list of functions, that is equivalent to:
[\x -> 1*x, \x -> 4*x, \x -> 2*x, \x -> 5*x]
Related
Let's say we have these 2 functions
f1 :: Int -> [Int] -> Int -> [Int]
f1 _ [] _ = []
f1 x (h:t) y = (x * h + y):(f1 x t y)
f2 :: [Int] -> Int
f2 (h:t) = h
Why does (f2 . f1 1 [1..10]) 1 work, but (f2 . f1 1) [1..10] 1 doesn't work?
All functions in Haskell take exactly one argument and return one value. The argument and/or the return type could be another function.
f1 has an argument type of Int and a return type of [Int] -> Int -> [Int]. The right associativity of (->) means we don't have to explicitly write this as
f1 :: Int -> ([Int] -> (Int -> [Int]))
but can instead drop the parentheses.
(Yes, (->) is an operator. You can use :k in GHCi to see the kind, but unfortunately what you get back is more complicated than we want to explain here:
> :k (->)
(->) :: TYPE q -> TYPE r -> *
Don't worry about what TYPE q and TYPE r stand for. Suffice it to say that (->) takes two types and returns a new type, and we can assume a simpler kind like
(->) :: * -> * -> *
The kind * is the kind of an ordinary type, more frequently written as Type these days.
)
In order to compose two functions, the return type of one must match the argument type of the other. We can see this from the type of (.) itself:
(.) :: (b -> c) -> (a -> b) -> a -> c
^ ^
That's not the case with f1 and f2:
-- vvvvvvvvvvvvvvvvvvvvv
f1 :: Int -> ([Int] -> Int -> [Int])
f2 :: [Int] -> Int
-- ^^^^^
-- [Int] -> Int -> [Int] and [Int] are different types
nor with f1 1 and f2
-- vvvvvvvvvvvv
f1 1 :: [Int] -> (Int -> [Int])
f2 :: [Int] -> Int
-- ^^^^^
-- Int -> [Int] and [Int] are different types
but it is true of f1 1 [1..10] and f2:
-- vvvvv
f1 1 [1..10] :: Int -> [Int]
f2 :: [Int] -> Int
-- ^^^^^
-- [Int] and [Int] are the same type
While (->) is right-associative, function application is left-associative, which is why we can write
((f1 1) [1..10]) 1
as f1 1 [1..10] 1 instead, leading to the appearance of f1 as taking 3 arguments, rather than an expression involving 3 separate function calls. You can see the three calls more clearly if you use a let expression to name each intermediate function explicitly:
let t1 = f1 1
t2 = t1 [1..10]
t3 = t2 1
in t3
As a complement to chepner's excellent answer, here's a less formal way of looking at it (which might be more intuitive if you haven't assimilated the formalities yet).
You seem to be thinking of (f . g) arg as a special syntactic form that will pass the argument to g and then call f on the result1. In fact this isn't what happens (or at best it's a shorthand for what happens).
Remember that functions are first class in Haskell. Frequently when that is brought up it means that we are passing functions as values to other functions, or storing them in data structures. But here what we need to remember is that first-class values can be computed as the result of expressions. f . g is an expression that computes a new function, in precisely the same manner that 7 + 9 is an expression that computes a new integer.
So (f . g) arg is not passing arg to g. It's passing arg to the function that is computed by the expression f . g. And if we had multiple arguments where arg is written, as in (f . g) x y z they would all be passed to the whole function f . g. There is no way for any of them to be passed to g directly.
The . operator builds a new function out of f and g by producing a function that behaves as follows: it takes a single argument x, passes it to g and then passes the result of that to f. In Haskell syntax that is basically (f . g) x = f (g x)2. So if we try to pass multiple arguments, as in (f . g) x y z, we end up with this:
(f . g) x y z = (f (g x)) y z
You can see this doesn't end up passing more arguments to g before g's result is fed to f; rather y and z end up being passed to the final result after x has been fed all the way through g and f (this is only going to work if f itself returns a function after being applied to one argument3). A simple way to think of it is that the first argument to the composed function "flows through the composition pipeline"; any other arguments will be passed to the result, after x has "flowed through". If we wanted the extra arguments to be passed to g, we should write it this way:
(f . g x y) z = f (g x y z)
Note that this reframes the "flow"; now it's z that is feeding through the composed functions. x and y have moved to being part of the definition of one of the two composed functions (g x y is every bit as much of an "expression that computes a function" as f . g is). If you really want the emphasis to be on x "flowing through" the composition pipeline, you'll need to change the way you defined g so that it takes arguments in a different order. This is a big part of why Haskellers frequently write functions to take the "main thing being operated on" as their last argument.
With all that in mind, your question should be pretty clear now.
In (f2 . f1 1 [1..10]) 1 the outermost 1 will "flow through the pipeline"; the first stage of the pipeline is f1 1 [1..10] (so the 1 will end up as a third argument to f1).
Whereas in (f2 . f1 1) [1..10] 1, the [1..10] will "flow through the pipeline", and the outer 1 will only be passed to the final result of the whole pipeline, not to the first stage of the pipeline. And the final result of the composition pipeline is the result of f2, which is a simple Int and cannot be applied to more arguments.
1 Haskell does have syntax for "pass multiple arguments to one function, then call another function on the result of that". However it's much more pedestrian. Just write f (g x y z). If this looks simpler to you than trying to twist it into a chain of function compositions, then just write it directly.
2 (f . g) x = f (g x) is almost the literal definition of the . operator. The real definition is f . g = \x -> f (g x). This definition is equivalent in the sense that it always produces exactly the same result, but it is usually a bit more efficient.
3 And your f2 example does not return a function after being applied to one argument (it just returns an Int), so we can see that (f2 . _anything_) arg1 arg2 is definitely going to be a type error with no further analysis, no matter what other function you're composing or what the two arguments are.
At the moment I am learning Haskell, but I am struggling with the syntax of a few example. What do they exactly mean?
First: What is the difference between these two lambdas (-> \y and y)?
lambda1 = \x -> \y -> x + y
lambda2 = \x y -> x + y
Second: What does this mean? Is this a lambda that act as a "pseudo" list generator that generates a list with 3 elements. How can I create such a list?
lambda3 = [\x -> x+1, \x -> 2*x, \x -> x^2]
Third: What does the \_ exactly mean?
lambda4 = \_ -> (\x -> x+1, \() -> 'a')
lambda2 is syntactic sugar for lambda1. All of these are equivalent:
f = \x -> \y -> x + y
f = \x y -> x + y
f x = \y -> x + y
f x y = x + y
f x y = (+) x y
f x = (+) x
f = (+)
lambda3 is a list of unary functions on numbers. Each function has the type (Num a) => a -> a, so the list has type (Num a) => [a -> a]. You could produce a list of values from this with map or a list comprehension:
fs = [\x -> x+1, \x -> 2*x, \x -> x^2]
map (\f -> f 3) fs
map ($ 3) fs
[f 3 | f <- fs]
==
[4, 6, 9]
lambda4 uses pattern-matching syntax. For example, if you have a data type:
data Foo = Foo Int String
Then you can write a lambda that pattern-matches on it:
f = \ (Foo n s) -> concat (replicate n s)
f (Foo 3 "bar") == "barbarbar"
(But unlike case, there is no way to provide alternative patterns if Foo has multiple constructors.)
The _ pattern just says “accept a value and ignore it”, so lambda4 is a function that accepts an argument, ignores it, and returns a pair (2-tuple) of unary functions, the first of type (Num a) => a -> a and the second of type () -> Char, so its type is Num a => r -> (a -> a, () -> Char).
lambda4 = \_ -> (\x -> x+1, \() -> 'a')
lambda4 = \ignored -> (\x -> x+1, \() -> 'a')
(inc, getA) = lambda4 ()
inc 3 == 4
getA () == 'a'
Functions that ignore their arguments can be constructed with the const function, and operator sections ((+ 1)) are typically preferred over lambdas (\x -> x + 1), so you can also write the above as:
lambda4 = const ((+ 1), const 'a')
On your second question, lambda3 is just a bad variable name. this is a list of functions of type Num a => a -> a. You can verify that by typing the following in ghci:
:t [\x -> x+1, \x -> 2*x, \x -> x^2]
First: What is the difference between these two lambdas (-> \y and y)?
There is no difference. Both produce the same output for the same input, and since they're pure functions, you can be sure that they produce no external effects that you wouldn't see.
The difference lies in that the first lambda uses syntactic sugar for currying.
\x y -> x + y is equal to \x -> \y -> x + y. Now, don't you think it looks a lot like type signatures, such as foo :: Int -> Int -> Int ? ;)
It means that the function foo takes 2 Int and produces an Int.
Since I don't have a very precise answer for the 2nd…
Third: What does the \_ exactly mean?
It's a lambda function (\) to which is associated the _ variable. _ is used as a placeholder to say “I don't care about the content of this variable, I'm even going to give it a proper name”.
There is no -> y. The correct way to read this is
(\ x -> (\ y -> (x + y)))
As it happens, Haskell has "curried functions", which means that
\ x y -> (x + y)
just happens to be equivalent to the above.
lambda3 is a list which contains three elements. Each of those elements happens to be a function. Functions are data in Haskell; you can pass them as arguments, return them as results, stuff them into lists, etc.
lambda3 = [ (\x -> x+1) , (\x -> 2*x) , (\x -> x^2) ]
lambda4 = \_ -> (\x -> x+1, \() -> 'a')
The "_" character basically means "I don't care what this is; ignore it". You can use it anywhere you can use a pattern. For example,
foobar x _ z = x + y
is a 3-argument function that completely ignores argument #2. Read about pattern matching and this should become clear. (I.e., it's not to do with lambdas, it's to do with patterns.)
Haskell newb here
I'm working on this problem in haskell:
(**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
* (compress '(a a a a b c c a a d e e e e))
(A B C A D E)
The solution (which I had to look up) uses foldr:
compress' :: (Eq a) => [a] -> [a]
compress' xs = foldr (\x acc -> if x == (head acc) then acc else x:acc) [last xs] xs
This foldr, according to the solution, takes two parameters, x and acc. It would seem like all foldr's take these parameters; is there any exception to this? Like a foldr that takes 3 or more? If not, is this convention redundant and can the formula be written with less code?
foldr takes a function of 2 arguments, but this doesn't prevent it from taking a function of 3 arguments provided that function has the right type signature.
If we had a function
g :: x -> y -> z -> w
With
foldr :: (a -> b -> b) -> b -> [a] -> b
Where we want to pass g to foldr, then (a -> b -> b) ~ (x -> y -> z -> w) (where ~ is type equality). Since -> is right associative, this means we can write g's signature as
x -> y -> (z -> w)
and its meaning is the same. Now we've produced a function of two parameters that returns a function of one parameter. In order to unify this with the type a -> b -> b, we just need to line up the arguments:
a -> | x ->
b -> | y ->
b | (z -> w)
This means that b ~ z -> w, so y ~ b ~ z -> w and a ~ x so g's type really has to be
g :: x -> (z -> w) -> (z -> w)
implying
foldr g :: (z -> w) -> [x] -> (z -> w)
This is certainly not impossible, although more unlikely. Our accumulator is a function instead, and to me this begs to be demonstrated with DiffLists:
type DiffList a = [a] -> [a]
append :: a -> DiffList a -> DiffList a
append x dl = \xs -> dl xs ++ [x]
reverse' :: [a] -> [a]
reverse' xs = foldr append (const []) xs $ []
Note that foldr append (const []) xs returns a function which we apply to [] to reverse a list. In this case we've given an alias to functions of the type [a] -> [a] called DiffList, but it's really no different than having written
append :: a -> ([a] -> [a]) -> [a] -> [a]
which is a function of 3 arguments.
As with all things in haskell have a look at the types of things to guide your way you can do this for any function in ghci.
Looking at this for foldr we see:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
This slightly abstract string can be written in english as:
foldr is a function that takes
1 ) a function with two parameters one of type a and one of type b and returns something of type b
2 ) A value of type b
3 ) A list of values of type a
And returns a value of type b
Where a and b are type variables (see here for a good tutorial on them) which can be filled in with any type you like.
It turns out that you can solve your compress problem using a foldr with a three-argument function.
compress :: Eq a => [a] -> [a]
compress [] = []
compress (z:zs) = z : foldr f (const []) zs z
where f x k w | x==w = k x
| otherwise = x : k x
Let's dissect that. First, we can improve readability by changing the last two lines to
where f x k = \w -> if x==w then k x else x : k x
This makes it evident that a ternary function is nothing but a binary function returning a unary function. The advantage of looking at it in this way is that foldr is best understood when passed a binary function. Indeed, we are passing a binary function, which just happens to return a function.
Let's focus on types now:
f :: a -> (a -> [a]) -> (a -> [a])
f x k
So, x::a is the element of the list we are folding on. Function k is the result of the fold on the list tail. The result of f x k is something having the same type as k.
\w -> if .... :: (a -> [a])
The overall idea behind this anonymous function is as follows. The parameter k plays the same role as acc in the OP code, except it is a function expecting the previous element w in the list before producing the accumulated compressed list.
Concretely, we use now k x when we used acc, passing on the current element to the next step, since by that time x will become the previous element w. At the top-level, we pass z to the function which is returned by foldr f (const []).
This compress variant is lazy, unlike the posted solution. In fact, the posted solution needs to scan the whole list before starting producing something: this is due to (\x acc -> ...) being strict in acc, and to the use of last xs. Instead, the above compress outputs list elements in a "streaming" fashion. Indeed, it works with infinite lists as well:
> take 10 $ compress [1..]
[1,2,3,4,5,6,7,8,9,10]
That being said, I think using a foldr here feels a bit weird: the code above is arguably less readable than the explicit recursion.
This question already has answers here:
What does $ mean/do in Haskell?
(2 answers)
Closed 6 years ago.
I'm having trouble with understanding how function application works with currying in haskell.
If I have following function:
($) :: (a -> b) -> a -> b
I understand that to partially apply this function I need to provide (a -> b) function ($'s first argument).
Why then is it possible to apply a value first (i.e. reverse arguments)?
($ 0) :: Num a => (a -> b) -> b
What am I missing here?
($) is an operator. In Haskell, any operator can be written in a left-section (like (x $)) or a right-section (like ($ x)):
(x $) = (\y -> x $ y) = ($) x
($ x) = (\y -> y $ x) = flip ($) x
Note that the only exception to this rule is (-), in order to conveniently write negative numbers:
\x -> (x-) :: Num a => a -> a -> a -- equivalent to \x -> (-) x
\x -> (-x) :: Num a => a -> a -- equivalent to \x -> negate x
In case you want to tersely write (\y -> y - x), you can use subtract:
\x -> subtract x :: Num a => a -> a -> a -- equivalent to \x -> flip (-) x
($ 0) ≡ (\x -> x $ 0) ≡ (\x -> ($) x 0)
If ($) :: (a -> b) -> a -> b) and we applied second argument like (\x -> ($) x 0) we have :: Num a => (a -> b) -> b
You are confusing the infix notation of an operator with a function.
> :t (($) (+1))
(($) (+1)) :: Num b => b -> b
Here are some forms of expressions with $, for better understanding:
a $ b => ($) a b
($ b) => flip ($) b => (\b a -> ($) a b) b => \a -> ($) a b
(a $) => ($) a => \b -> ($) a b
Note also that in Haskell syntax, alphanumeric names are distinguished from punctuation names.
An alphanumeric function foo1 a b is prefix by default, and becomes infix if you add backticks: a `foo` b.
A punctuation-named function like $ or <*> is infix by default, and becomes prefix if you add parentheses ($) or (<*>). This is just syntax sugar for the programmer familiar with the Latin alphabet; it is an arbitrary but helpful distinction between alphanumeric names and punctuation names.
Both kinds of functions are just functions, they don't have the special semantic rules that we have for "operators" in C++ or Java. It's just the syntax rules around prefix/infix and backticks/parentheses that are different between punctuation-named functions and alphanumeric-named functions.
Why is the type of this function (a -> a) -> a?
Prelude> let y f = f (y f)
Prelude> :t y
y :: (t -> t) -> t
Shouldn't it be an infinite/recursive type?
I was going to try and put into words what I think it's type should be, but I just can't do it for some reason.
y :: (t -> t) -> ?WTFIsGoingOnOnTheRHS?
I don't get how f (y f) resolves to a value. The following makes a little more sense to me:
Prelude> let y f x = f (y f) x
Prelude> :t y
y :: ((a -> b) -> a -> b) -> a -> b
But it's still ridiculously confusing. What's going on?
Well, y has to be of type (a -> b) -> c, for some a, b and c we don't know yet; after all, it takes a function, f, and applies it to an argument, so it must be a function taking a function.
Since y f = f x (again, for some x), we know that the return type of y must be the return type of f itself. So, we can refine the type of y a bit: it must be (a -> b) -> b for some a and b we don't know yet.
To figure out what a is, we just have to look at the type of the value passed to f. It's y f, which is the expression we're trying to figure out the type of right now. We're saying that the type of y is (a -> b) -> b (for some a, b, etc.), so we can say that this application of y f must be of type b itself.
So, the type of the argument to f is b. Put it all back together, and we get (b -> b) -> b — which is, of course, the same thing as (a -> a) -> a.
Here's a more intuitive, but less precise view of things: we're saying that y f = f (y f), which we can expand to the equivalent y f = f (f (y f)), y f = f (f (f (y f))), and so on. So, we know that we can always apply another f around the whole thing, and since the "whole thing" in question is the result of applying f to an argument, f has to have the type a -> a; and since we just concluded that the whole thing is the result of applying f to an argument, the return type of y must be that of f itself — coming together, again, as (a -> a) -> a.
Just two points to add to other people's answers.
The function you're defining is usually called fix, and it is a fixed-point combinator: a function that computes the fixed point of another function. In mathematics, the fixed point of a function f is an argument x such that f x = x. This already allows you to infer that the type of fix has to be (a -> a) -> a; "function that takes a function from a to a, and returns an a."
You've called your function y, which seems to be after the Y combinator, but this is an inaccurate name: the Y combinator is one specific fixed point combinator, but not the same as the one you've defined here.
I don't get how f (y f) resolves to a value.
Well, the trick is that Haskell is a non-strict (a.k.a. "lazy") language. The calculation of f (y f) can terminate if f doesn't need to evaluate its y f argument in all cases. So, if you're defining factorial (as John L illustrates), fac (y fac) 1 evaluates to 1 without evaluating y fac.
Strict languages can't do this, so in those languages you cannot define a fixed-point combinator in this way. In those languages, the textbook fixed-point combinator is the Y combinator proper.
#ehird's done a good job of explaining the type, so I'd like to show how it can resolve to a value with some examples.
f1 :: Int -> Int
f1 _ = 5
-- expansion of y applied to f1
y f1
f1 (y f1) -- definition of y
5 -- definition of f1 (the argument is ignored)
-- here's an example that uses the argument, a factorial function
fac :: (Int -> Int) -> (Int -> Int)
fac next 1 = 1
fac next n = n * next (n-1)
y fac :: Int -> Int
fac (y fac) -- def. of y
-- at this point, further evaluation requires the next argument
-- so let's try 3
fac (y fac) 3 :: Int
3 * (y fac) 2 -- def. of fac
3 * (fac (y fac) 2) -- def. of y
3 * (2 * (y fac) 1) -- def. of fac
3 * (2 * (fac (y fac) 1) -- def. of y
3 * (2 * 1) -- def. of fac
You can follow the same steps with any function you like to see what will happen. Both of these examples converge to values, but that doesn't always happen.
Let me tell about a combinator. It's called the "fixpoint combinator" and it has the following property:
The Property: the "fixpoint combinator" takes a function f :: (a -> a) and discovers a "fixed point" x :: a of that function such that f x == x. Some implementations of the fixpoint combinator might be better or worse at "discovering", but assuming it terminates, it will produce a fixed point of the input function. Any function that satisfies The Property can be called a "fixpoint combinator".
Call this "fixpoint combinator" y. Based on what we just said, the following are true:
-- as we said, y's input is f :: a -> a, and its output is x :: a, therefore
y :: (a -> a) -> a
-- let x be the fixed point discovered by applying f to y
y f == x -- because y discovers x, a fixed point of f, per The Property
f x == x -- the behavior of a fixed point, per The Property
-- now, per substitution of "x" with "f x" in "y f == x"
y f == f x
-- again, per substitution of "x" with "y f" in the previous line
y f == f (y f)
So there you go. You have defined y in terms of the essential property of the fixpoint combinator:
y f == f (y f). Instead of assuming that y f discovers x, you can assume that x represents a divergent computation, and still come to the same conclusion (iinm).
Since your function satisfies The Property, we can conclude that it is a fixpoint combinator, and that the other properties we have stated, including the type, are applicable to your function.
This isn't exactly a solid proof, but I hope it provides additional insight.