在没有使用lambda函数或定义另一个“本地”函数的情况下,Haskell中是否有一种方法可以绑定第二个参数而不是第一个函数?
实施例。我有一个二进制函数,如:
sub :: Int -> Int -> Int
sub x y = x - y
现在,如果我想绑定第一个参数,我可以轻松地使用(sub someExpression):
mapSubFrom5 x = map (sub 5) x
*Main> mapSubFrom5 [1,2,3,4,5]
[4,3,2,1,0]
如果我想绑定前n个参数而没有“gap”,那就行了。
如果我想绑定第二个参数而不是第一个参数,我知道的两个选项更详细:
通过另一个本地函数:
mapSub5 x = map sub5 x
where sub5 x = sub x 5
*Main> mapSub5 [1,2,3,4,5]
[-4,-3,-2,-1,0]
或者使用lambda:
mapSub5 x = map (\x -> sub x 5) x
虽然两者都工作正常,但我喜欢“sub 5”的优雅,并想知道是否有一种类似的优雅方式来绑定函数的第n(n> 1)个参数?
答案 0 :(得分:32)
flip
,它产生了一个反转前两个参数的新函数,已经被提到作为一个直接的解决方案。
然而,值得注意的是Haskell为二元运算符定义了一个漂亮的中缀语法。
首先,它只是
sub = (-)
括号括起来,所有操作符都是 - 通常也是 - 普通函数。现在我们可以用一些特殊的语法来操作运算符。绑定到第一个操作数:
addOne = (1 +)
......和第二个
half = (/ 2)
因此您的代码变为
map (-5) [1..5]
不幸的是,-5
是一个数字文字,但你明白了。 :)现在我们可以通过在
f x y == x `f` y
我们可以使用这种特殊的运算符语法来编写
map (`sub` 5) [1..5]
<小时/> 注意:讨论第一个参数很常见,第二个参数 - 就像你的情况一样 - 很可能。但是:我不会为了进一步的争论而这样做。 Haskell函数是以一种风格编写的,正如那个原因,常见的咖喱函数就在前面。
使用一些特殊的语法来进一步论证对我来说太隐晦了。只需使用lambda并为变量提供描述性名称。
答案 1 :(得分:9)
如何绑定第二个参数:
div2 = flip div 2
ghci> div2 10
5
在你的情况下,你可以写
ghci> map (flip (-) 5) [1..5]
[-4,-3,-2,-1,0]
请注意,在Haskell中,您可以将前缀形式的运算符编写为(-)
。它与您问题中的sub
相同。
答案 2 :(得分:9)
对于n = 2,只有另一种绑定方式:
mapSub5 x = map (`sub` 5) x