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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With