Currying减法

时间:2010-12-15 20:29:10

标签: haskell coding-style

如果我们要映射一个增加范围的每个元素的函数,我们可以写

map (\x -> x + 1) [1..5]

但我想大多数人都会选择

map (+1) [1..5]

代替。但这显然不适用于(-1),因为那是负面的。

首先想到的是

map (+(-1)) [1..5]

考虑到Prelude(x - y = x + negate y)中如何定义减法,这是有意义的,但对我来说看起来有点奇怪。然后我想出了

map (flip (-) 1) [1..5]

这对我来说看起来更好,但可能有点太复杂了。

现在我知道这没什么大不了的,但我想知道我是否错过了一个更明显的方法来写这个?如果没有,您更喜欢哪两种方式?我真的只是问,因为通常这样的小细节会让你的代码更加惯用,因此对于那些必须阅读它的开发人员来说也是如此。

解决方案

现在我得到了几个答案,我认为我个人最喜欢的是

map (subtract 1) [1..5]

接着是

map pred [1..5]

主要是因为第一个是非常明确的,没有人需要猜测/查找pred的含义(前任)。

4 个答案:

答案 0 :(得分:42)

如果您想要缩小右侧部分,可以使用subtract函数代替-

map (subtract 1) [1..5]

答案 1 :(得分:9)

由于-是中缀减法和前缀否定,因此您不能使用(*x) -(其中*是中缀运算符和x值)语法negate。幸运的是Prelude附带subtract\x -> -x,分别是\x y -> y-x和{{1}},因此您可以使用那些需要区分两者的地方。

答案 2 :(得分:2)

我认为map (\x -> x - 1) [1..5]更好地传达了程序员的意图,因为毫无疑问从什么中减去了什么。我也找到了你的第一个解决方案map (+(-1)) [1..5],也很容易阅读。

答案 3 :(得分:2)

我不喜欢subtract,因为它令人困惑地倒退了。我建议

minus :: Num n => n -> n -> n
minus = (-)
infixl 6 `minus`

然后你可以写

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