【问题标题】:Currying subtraction柯里化减法
【发布时间】:2011-05-26 04:04:19
【问题描述】:

如果我们想映射一个函数,将范围内的每个元素都加 1,我们可以这样写

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 的含义(前身)。

【问题讨论】:

  • 一个小提示:问题不是柯里化,而是操作符部分的语法。 (-) 1 是一种(在语法上有效)部分应用 curried - 函数的方法。
  • 我一直在为此苦苦挣扎,但想不出更好的办法。 map ((-) 1) [1..5] 也不起作用,因此带有翻转的版本。
  • 如果它们是整数,而你只想减1,为什么不map pred
  • @Grazer 因为我对此一无所知,所以我是否遗漏了一些明显的问题。

标签: haskell coding-style


【解决方案1】:

如果你想右部分减法,你可以使用subtract函数代替-

map (subtract 1) [1..5]

【讨论】:

  • 我的意思很明显,谢谢!有时,您就是只见树木不见森林,Hoogle 等等。
【解决方案2】:

由于- 既是中缀减法又是前缀否定,因此您不能对- 使用(*x)(其中* 是中缀运算符,x 是值)语法。幸好Prelude自带negatesubtract,分别是\x -> -x\x y -> y-x,这样你就可以在需要区分两者的地方使用。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      那你就可以写了

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

      【讨论】:

      • 我更喜欢(+(-1))。使用新名称的技巧很好,但它占用了一个有价值的名称。太糟糕了(`-` 1) 语法无效。
      【解决方案5】:

      自从提出这个问题多年后,在 GHC 9 中,我们现在有了 LexicalNegation 扩展允许(- 1) 部分,只要我们使用空格将减号与数字分开。

      确实,启用扩展后,我们有:

      > map (subtract 1) [1..5]       -- still works, of course
      [0, 1, 2, 3, 4]
      
      > map (- 1) [1..5]              -- with whitespace
      [0, 1, 2, 3, 4]                 -- (- 1) is now a section
      
      > map (-1) [1..5]               -- no whitespace
      *error*                         -- (-1) is now a negative literal
      

      【讨论】:

        猜你喜欢
        • 2016-01-01
        • 2011-08-18
        • 1970-01-01
        • 1970-01-01
        • 2021-04-04
        • 2015-08-17
        • 2017-01-20
        • 2018-01-24
        相关资源
        最近更新 更多