开发者

How can I bind the second argument in a function but not the first (in an elegant way)?

开发者 https://www.devze.com 2023-02-01 08:31 出处:网络
Is there a way in Haskell to bind the second argument but not the first of a function without using lambda functions or defining another \"local\" function?

Is there a way in Haskell to bind the second argument but not the first of a function without using lambda functions or defining another "local" function?

Example. I have a binary function like:

sub :: Int -> Int -> Int
sub x y = x - y 

Now if I want to bind the first argument, I can do so easily using (sub someExpression):

mapSubFrom5 x = map (sub 5) x

*Main> mapSubFrom5 [1,2,3,4,5]
[4,3,2,1,0]

That works fine if I want to bind the first n arguments without "gap".

If I want to bind the second argument but not the first, the two options I am aware of are more verbose:

Either via another, local, function:

mapSub5 x = map sub5 x
    where sub5 x = sub x 5

*Main> mapSub5 [1,2,3,4,5]
[-4,-3,-2,-1,0]

Or using lambda:

mapSub5 x = map (\x -> sub x 5) x

While both are working fine, I like the elegance of "sub 5" and wonder if the开发者_JAVA百科re is a similarly elegant way to bind the n-th (n > 1) argument of a function?


flip, which produces a new function with the first two arguments inversed, has already been mentioned as a straigtforward solution.

However, it's worth noting that Haskell defines a nice infix syntax for binary operators.

First of all, it's simply

sub = (-)

With parentheses around, all operators are - syntactially too - ordinary functions. Now we can curry operators with some special syntax. Binding to the first operand:

addOne = (1 +)

... and to the second

half = (/ 2)

Thus your code becomes

map (-5) [1..5]

Unfortunately, -5 is a number literal, but you get the point. :) Now since we can turn any function into a binary operator by putting backticks around it like in

f x y == x `f` y

we can use this special operator syntax to write

map (`sub` 5) [1..5]


Note: Currying the first argument is common, the second one - as in your case - nicely possible. But: I wouldn't do that for futher arguments. Haskell functions are written in a style that the common ones to curry are in the front for exactly that reason.

Using some special syntax for further arguments feels much too implicit for me. Just use the lambda and give the variables descriptive names.


For n=2 only another way to bind:

mapSub5 x = map (`sub` 5) x


How to bind the second argument:

div2 = flip div 2

ghci> div2 10
5

In your case you can write

ghci> map (flip (-) 5) [1..5]
[-4,-3,-2,-1,0]

Note that in Haskell you can write operators in prefix form as (-). It is the same as sub in your question.

0

精彩评论

暂无评论...
验证码 换一张
取 消