Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 something, because it'd need the numbers to be after the ^, not before.

like image 326
devoured elysium Avatar asked Jan 16 '11 03:01

devoured elysium


2 Answers

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.)

like image 179
luqui Avatar answered Sep 30 '22 20:09

luqui


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.

like image 33
Gabe Avatar answered Sep 30 '22 20:09

Gabe