Why do both map (^2) xs and map (2^) xs work as expected in Haskell?
Why does
map (^2) [1..10]
work and also
map (2^) [1..10]
work?
I'd expect it only to work with one of them, not for both.
I thought map would iterate over all the elements of [1..10]
and then do
[1^2, 2^2, 3^2, ...]
for map (^2) [1..10]
. Then I'd expect that when given map (2^) [1..10]
, it'd yield a sintax error or 开发者_StackOverflow社区something, because it'd need the numbers to be after the ^
, not before.
The Haskell grammar has special support for construct like this, called "operator sections". If you have any infix operator, like say #$%
, then the following notation is supported:
(#$%) = \x y -> x #$% y
(#$% y) = \x -> x #$% y
(x #$%) = \y -> x #$% y
So you are expecting some mathematical consistency to break this, and if Haskell were a miniscule language like Forth, I would be inclined to agree with your intuition. The reason it works is basically "because they wrote it to work like that".
(It was added also to reduce ambiguity - does f + x
mean f
applied to two arguments, or does it mean +
applied to two arguments? Since it actually means the latter, how do we represent the former? Answer: using ()
to introduce an operator section.)
Haskell knows that ^
is an infix operator so it interprets (in mathematical notation) (2^)
as f(x) = 2^x
and (^2)
as f(x) = x^2
.
(2 ^) creates a new function that takes a parameter and invocates (2 ^ parameter). It is a way of curryfication.
Here's a link with the theory behind it: Partial Application(Haskell.org)
精彩评论