Haskell在指定参数类型时抛出错误

时间:2015-07-17 09:21:36

标签: haskell ghci

我刚开始学习Haskell。我试图实现一个函数,它接受一个数字作为它的输入,并根据它的值返回-1,0或1。输入可以是任何数字(整数或浮点)。这是代码:

signum :: (Num a) => a -> Int
signum x
    | x > 0 = 1
    | x < 0 = -1
    | otherwise = 0

但是当我尝试将其加载到 ghci 时,它会显示以下错误:

[1 of 1] Compiling Main             ( run_it.hs, interpreted )

run_it.hs:7:13:
Could not deduce (Ord a) arising from a use of `>'
from the context (Num a)
  bound by the type signature for Main.signum :: Num a => a -> Int
  at run_it.hs:5:11-29
Possible fix:
  add (Ord a) to the context of
    the type signature for Main.signum :: Num a => a -> Int
In the expression: x > 0
In a stmt of a pattern guard for
               an equation for `signum':
  x > 0
In an equation for `signum':
    signum x
      | x > 0 = 1
      | x < 0 = - 1
      | otherwise = 0
Failed, modules loaded: none.

这个错误是什么意思?

1 个答案:

答案 0 :(得分:6)

方法>Ord类中定义,因此您需要为类型签名添加其他约束:

signum :: (Ord a, Num a) => a -> Int

在GHCi中,您可以使用:i <Class>查看类的方法,例如:

*Main> :i Ord
class Eq a => Ord a where
  compare :: a -> a -> Ordering
  (<) :: a -> a -> Bool
  (<=) :: a -> a -> Bool
  (>) :: a -> a -> Bool
  (>=) :: a -> a -> Bool
  [...]

或者,您可以检查方法本身:

*Main> :i (>)
class Eq a => Ord a where
  ...
  (>) :: a -> a -> Bool
  ...
    -- Defined in ‘GHC.Classes’
infix 4 >

原始signum没有此约束的原因是因为它不使用Ord中的方法。相反,它使用专门针对某个类型的函数(如ltInt)或模式匹配(请参阅Word实例):https://hackage.haskell.org/package/base-4.8.0.0/docs/src/GHC-Num.html#signum