使用守卫舍入 Haskell 中的负数

Rounding Negative Numbers in Haskell Using a Guard

我是 Haskell 的新手,所以我不太清楚如何在守卫中操纵操作顺序或对我在守卫中的 'where' 表达式施加更多限制。 这是我在 Haskell 中的第一个程序,其中有一些需要遵循的神秘评分方案,它 return 是你的字母等级。它适用于所有非负输入,但 round 函数似乎在负输入上失败。这是我的代码:

roundMark :: Float -> Integer
roundMark mark
    | mark2 < 0 = 0
    | mark2 > 100 = 100
    | otherwise = mark2
    where mark2 = round mark

letterGrade :: Float -> Char
letterGrade mark 
    | newMark < 48 = 'F'
    | newMark >= 48 && newMark < 65 = 'C'
    | newMark >= 65 && newMark < 79 = 'B'
    | otherwise = 'A'
    where newMark = roundMark mark

对于负输入,我收到错误

No instance for (Num (Float -> Char)) arising from a use of ‘-’
        (maybe you haven't applied a function to enough arguments?)

我想知道是否有办法在尝试使用 round 函数之前将负输入的 where 表达式限制为 return 0,或者我是否可以将我的警卫放在有条件的。

  1. round 是 "bankers rounding" 或 "round to even" 但您可能(?)想要整数截断,例如 floor.

  2. 这种情况下四舍五入的目的是什么?一个负数仍然小于 48,并且仍然会导致 F,就像值 0 一样。

  3. 如果您想将所有负数舍入为零,而不仅仅是将负数 mark2 舍入为零,那么只需使用正确的变量:

.

roundMark :: Float -> Integer
roundMark mark
    | mark < 0 = 0      -- See this line, use `mark` vs `mark2`.
    | mark2 > 100 = 100
    | otherwise = mark2
    where mark2 = round mark

这里的关键是letterGrade -1letterGrade (-1)的区别。 letterGrade -1 表示取 letterGrade 的值并减去 1letterGrade (-1) 表示将函数 letterGrade 应用于值 -1。这是因为 - 在这两种情况下都是运算符。 -1 不是数字 "negative one"。相反,它是由符号 - 和整数值 1 表示的运算符。问题是 - 运算符有两种风格:一元和二元。为了区分 - 的这两种用法,Haskell 的创建者决定使用 (-1) 来表示采用给定数字的 "negative" 的一元运算符。没有括号,- 是二进制减法运算符。

有关此主题的进一步讨论,请参阅 及其链接的问题。