使用Guard在Haskell中舍入负数

时间:2018-01-13 01:42:46

标签: haskell functional-programming guard

我是Haskell的新手,所以我不太清楚如何操纵一个后卫中的操作顺序,或者在一个后卫的'where'表达中加入更多的限制。 这是我在Haskell的第一个程序,其中有一些神秘的标记方案需要遵循,它会返回你的字母等级。它适用于所有非负输入,但圆负功能似乎在负输入时失败。这是我的代码:

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 where表达式设置为负输入返回0,或者我是否可以在有条件的情况下保护我。

2 个答案:

答案 0 :(得分:4)

  1. round是&#34;银行家四舍五入&#34;或者&#34;围绕甚至&#34;但你可能(?)想要整数截断,例如floor

  2. 在这种情况下舍入的目的是什么?负数仍然小于48,仍然会产生F,就像值0一样。

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

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

答案 1 :(得分:4)

此处的关键是CGLGetCurrentContext()letterGrade -1之间的区别。 letterGrade (-1)表示取letterGrade -1的值并减去letterGrade1表示要将函数letterGrade (-1)应用于值letterGrade。这是因为-1在两种情况下都是运算符。 -不是数字&#34;负数#&#34;。相反,它是由符号-1和整数值-表示的运算符。问题是1运算符有两种风格:一元和二元。为了区分-的这两种用法,Haskell的创建者决定使用-来表示采用&#34;否定&#34;的一元运算符。给定数字。没有括号,(-1)是二元减法运算符。

有关此主题的进一步讨论,请参阅Why is the unary minus operator problematic in this expression: (- 2) 1?及其相关问题。