如果我们要映射一个增加范围的每个元素的函数,我们可以写
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
的含义(前任)。
答案 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]