使用保护在Haskell中舍入负数

使用保护在Haskell中舍入负数,haskell,functional-programming,guard,Haskell,Functional Programming,Guard,我是Haskell的新手,所以我不太知道如何操纵guard中的操作顺序,或者对guard中的“where”表达式施加更多限制。 这是我在Haskell的第一个程序,其中有一些神秘的评分方案需要遵循,它会返回你的字母分数。它适用于所有非负输入,但round函数在负输入上似乎失败。这是我的密码: roundMark :: Float -> Integer roundMark mark | mark2 < 0 = 0 | mark2 > 100 = 100 |

我是Haskell的新手,所以我不太知道如何操纵guard中的操作顺序,或者对guard中的“where”表达式施加更多限制。 这是我在Haskell的第一个程序,其中有一些神秘的评分方案需要遵循,它会返回你的字母分数。它适用于所有非负输入,但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
我想知道在尝试使用round函数之前,是否有一种方法可以限制where表达式返回0作为负输入,或者是否可以在条件表达式中设置保护

round是四舍五入或四舍五入到偶数,但您可能需要整数截断,例如floor

在这种情况下,舍入的目的是什么?负数仍然小于48,并且仍然会产生与值0相同的F

如果要将所有负数舍入为零,而不是仅将负数mark2舍入为零,则只需使用正确的变量:

round是四舍五入或四舍五入到偶数,但您可能需要整数截断,例如floor

在这种情况下,舍入的目的是什么?负数仍然小于48,并且仍然会产生与值0相同的F

如果要将所有负数舍入为零,而不是仅将负数mark2舍入为零,则只需使用正确的变量:


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


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

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



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

负数失败是什么意思?如我所知,使用“-”可能没有将函数应用到足够的参数中,从而导致Num Float->Char出现错误。请在问题中发布完整错误。表面上看,我看不到任何会导致这样的错误的东西。这看起来像是编译时错误,而不是运行时错误。它不应该只显示某些输入。它指向哪里?在这段代码的任何地方都不使用-我用letterGrade-1代替了letterGrade-1尝试了我的函数。我不知道它们是不同的东西。谢谢。你说负数失败是什么意思?正如在我得到的错误一样,Num Float->Char没有实例是由使用“-”引起的,也许你没有对足够的参数应用函数?在问题中发布完整的错误。表面上看,我看不到任何会导致这样的错误的东西。这看起来像是编译时错误,而不是运行时错误。它不应该只显示某些输入。它指向哪里?在这段代码的任何地方都不使用-我用letterGrade-1代替了letterGrade-1尝试了我的函数。我不知道它们是不同的东西。谢谢。我想要四舍五入,这样我就可以四舍五入到最接近的整数,比如47.8就得到了48,它变成了C而不是F。但是无论如何,谢谢你的帮助。我甚至不需要一个where就修好了我的,只是为了让我的生活更简单。按照美国的说法,把分数提高到.5或更高,然后加上一个,然后截断。在美国,我们不把100的分数提高到101,@ThomasM.DuBuisson。您可能想添加0.5,然后截断0.1。我想要四舍五入,这样我就可以四舍五入到最接近的整数,比如47.8就得到了48,它变成了C而不是F。但是无论如何,谢谢你的帮助。我甚至不需要一个where就修好了我的,只是为了让我的生活更简单。按照美国的说法,把0.5和更高的整数加起来,然后加上一个,然后截断。我们不把100加起来,不是吗
o 101在美国,@ThomasM.DuBuisson。你可能想加上0.5,然后截断。大多数情况下,一元负号在实践中与括号一起使用,但更准确地说,它是一种语法形式,如do、let或lambda,所以像letterGrade$-1这样的表达式也是有效的。大多数情况下,一元负号在实践中与括号一起使用,但更准确地说,它是一种类似do、let或lambda的语法形式,所以像letterGrade$-1这样的表达式也是有效的。
No instance for (Num (Float -> Char)) arising from a use of ‘-’
        (maybe you haven't applied a function to enough arguments?)
roundMark :: Float -> Integer
roundMark mark
    | mark < 0 = 0      -- See this line, use `mark` vs `mark2`.
    | mark2 > 100 = 100
    | otherwise = mark2
    where mark2 = round mark