views:

178

answers:

4

Is there an elegant notation for Currying the arguments of a function out of order in Haskell?

For example, if you wish to divide 2 by all elements of a list, you can write

map ((/) 2) [1,2,3,4,5]

However to divide all elements of a list it seems you need to define an anonymous function

map (\x -> x/2) [1,2,3,4,5]

Anonymous functions quickly become unwieldy in more complex cases. I'm aware that in this case map ((*) 0.5) [1,2,3,4,5] would work fine, but I'm interested to know if Haskell has a more elegant way of currying arguments of a function out of order?

+7  A: 

In this particular case:

Prelude> map (/2) [1..5]
[0.5,1.0,1.5,2.0,2.5]

Not only you can use an infix operator as ordinary prefix function, you can also partially apply it in infix form. Likewise, the first example would better be written as map (2/) [1..5]

Also, there's flip which is not quite as elegant, but still the best option available for ordinary functions (when you don't want to turn them into infix via backticks):

Prelude> let div' = (/)
Prelude> div' 2 1
2.0
Prelude> flip div' 2 1
0.5
delnan
Does this only work with operators? What about arbitrary functions?
Gabe
@Gabe: As FUZxxl wrote, it also works with functions that are used infix (by surrounding them with backticks). I'd provide an example, but he already provided one.
delnan
Thank you. It is a shame there is no syntax such as f 1 2 # 4 #, that has the same effect as \x y -> f 1 2 x 4 y.
hosiers
@hosiers: Actually, for tuples there is an extension for this: Stick `{-# LANGUAGE TupleSections #-}` on top and you can do `('a',,1,,)` instead of `\x y z -> ('a',x,1,y,z)`, but for functions - I've yet to see this.
FUZxxl
+2  A: 

For your second one, the lambda is unnecessary, just use like:

map (/2) [1..5]

The form (/2) simply means, that you want to access the second param of an operator. It is also possible with the first argument (2/). This is called a section, and is a really useful hack, not only in code golf. You can also use it in prefix functions, if you use them infix:

map (`div` 2) [1..5]

In more difficult cases, like 3 or more arguments, you're supposed to use lambdas, as it becomes more readable most times.

FUZxxl
+2  A: 

I think you are looking for a generalized solution, like the cut in scheme. Right?

There is the flip function that reverse the first 2 arguments of a function. There may be other functions doing a similar task (I'm not too good at Haskell... yet).

gawi
`flip` doesn't reverses the argument list. It Just flips the first two, consider this: `flip (.) :: (a -> b) -> (b -> c) -> a -> c`. -1
FUZxxl
A: 

I encountered a very similar issue myself recently, and I wasn't able to find an elegant solution other than using a helper function to do it:

dbfunc f b c = (\a -> liftIO $ f a b c)
deleteAllRows = do
  ask >>= dbfunc run "delete from t1" []

At least this pattern is common enough in HDBC that dbfunc is reusable.

Gaius