haskell - 编译错误 - 无法推断 Ord

标签 haskell types

nRaizes :: Floating a => a -> a -> a -> a
  nRaizes a b c = let r = b^2 - 4 * a * c
                  in if r < 0
                     then 0
                     else if r == 0
                     then 1
                     else 2

所以我得到了这段代码,我在其中检查方程的根数。但是当我尝试编译它时,它给了我这个。

 Could not deduce (Ord a) arising from a use of ‘<’
    from the context (Floating a)
      bound by the type signature for
                 nRaizes :: Floating a => a -> a -> a -> a
      at Ficha1.hs:29:14-43
    Possible fix:
      add (Ord a) to the context of
        the type signature for nRaizes :: Floating a => a -> a -> a -> a
    In the expression: r < 0
    In the expression: if r < 0 then 0 else if r == 0 then 1 else 2
    In the expression:
      let r = b ^ 2 - 4 * a * c
      in if r < 0 then 0 else if r == 0 then 1 else 2

Ficha1.hs:33:32:
    Could not deduce (Eq a) arising from a use of ‘==’
    from the context (Floating a)
      bound by the type signature for
                 nRaizes :: Floating a => a -> a -> a -> a
      at Ficha1.hs:29:14-43
    Possible fix:
      add (Eq a) to the context of
        the type signature for nRaizes :: Floating a => a -> a -> a -> a
    In the expression: r == 0
    In the expression: if r == 0 then 1 else 2
    In the expression: if r < 0 then 0 else if r == 0 then 1 else 2

是的,我是一个初学者。我真的无法理解出了什么问题。是一个 float ,为什么不能比较呢? 我只知道它与签名有关,因为如果我删除它,它会起作用

最佳答案

It's a floating number, why can't it compare it?

不,它本身不是 float 。 Floating 严格来说是指可以对它执行三角函数双曲线函数。这是否意味着它是一个 float ,是一个不同的方面(尽管它有点相关)。

话虽如此,它确实暗示你可以比较两个元素。然而这不是问题:我们可以将类型类 Ord a 添加到它:

nRaizes :: <b>(Floating a, Ord a)</b> => a -> a -> a -> a
nRaizes a b c = let r = b^2 - 4 * a * c
                  in if r < 0
                     then 0
                     else
                         if r == 0
                         then 1
                         else 2

但我们对函数的定义过于严格。为什么我们在这里需要三角函数和双曲函数?为什么不用Ord 定义*所有可能的数字表示的函数?因此,我们可以将函数推广到:

nRaizes :: (<b>Num</b> a, Ord a) => a -> a -> a -> a
nRaizes a b c = let r = b^2 - 4 * a * c
                  in if r < 0
                     then 0
                     else
                         if r == 0
                         then 1
                         else 2

此外,尽管大多数人都喜欢圣诞节。大多数程序员不喜欢圣诞树作为函数定义。也许更优雅的方法是使用守卫而不是 if-then-elses:

nRaizes :: (Num a, Ord a) => a -> a -> a -> a
nRaizes a b c <b>| r < 0 = 0
              | r == 0 = 1
              | otherwise = 2
    where r = b*b - 4*a*c</b>

最后我们产生三个可能的输出:012。但是没有说输出的类型应该与abc的类型相同。所以我们可以把输入输出的类型拆分成:

nRaizes :: (Num a, Ord a<b>, Num b</b>) => a -> a -> a -> <b>b</b>
nRaizes a b c | r < 0 = 0
              | r == 0 = 1
              | otherwise = 2
    where r = b*b - 4*a*c

关于haskell - 编译错误 - 无法推断 Ord,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46502513/

相关文章:

Haskell:为什么 'id' 使这个函数不再是单子(monad)函数?

python - 在 Python/Eclipse 中将对象的注释键入正确的类

wpf - slider 最小值/最大值绑定(bind)到 Int 常量

powershell - 通过 PowerShell 命令获取返回对象的类 - 确定 cmdlet 的输出数据类型

Haskell,范围缩小到无步骤

haskell - f x 的优先级和结合性是多少? haskell

haskell - 光线追踪并找到交点处表面的法向量

haskell - 如何在haskell中重复函数列表

c++ - 在处理模板时,如何避免在函数头和函数体中两次声明相同的类型?

php - 如何在实例化对象之前将 PHP 变量定义为特定的类类型?