使用守卫舍入 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,或者我是否可以将我的警卫放在有条件的。
round
是 "bankers rounding" 或 "round to even" 但您可能(?)想要整数截断,例如 floor
.
这种情况下四舍五入的目的是什么?一个负数仍然小于 48,并且仍然会导致 F,就像值 0 一样。
如果您想将所有负数舍入为零,而不仅仅是将负数 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 -1
和letterGrade (-1)
的区别。 letterGrade -1
表示取 letterGrade
的值并减去 1
。 letterGrade (-1)
表示将函数 letterGrade
应用于值 -1
。这是因为 -
在这两种情况下都是运算符。 -1
不是数字 "negative one"。相反,它是由符号 -
和整数值 1
表示的运算符。问题是 -
运算符有两种风格:一元和二元。为了区分 -
的这两种用法,Haskell 的创建者决定使用 (-1)
来表示采用给定数字的 "negative" 的一元运算符。没有括号,-
是二进制减法运算符。
有关此主题的进一步讨论,请参阅 及其链接的问题。
我是 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,或者我是否可以将我的警卫放在有条件的。
round
是 "bankers rounding" 或 "round to even" 但您可能(?)想要整数截断,例如floor
.这种情况下四舍五入的目的是什么?一个负数仍然小于 48,并且仍然会导致 F,就像值 0 一样。
如果您想将所有负数舍入为零,而不仅仅是将负数
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 -1
和letterGrade (-1)
的区别。 letterGrade -1
表示取 letterGrade
的值并减去 1
。 letterGrade (-1)
表示将函数 letterGrade
应用于值 -1
。这是因为 -
在这两种情况下都是运算符。 -1
不是数字 "negative one"。相反,它是由符号 -
和整数值 1
表示的运算符。问题是 -
运算符有两种风格:一元和二元。为了区分 -
的这两种用法,Haskell 的创建者决定使用 (-1)
来表示采用给定数字的 "negative" 的一元运算符。没有括号,-
是二进制减法运算符。
有关此主题的进一步讨论,请参阅