为什么我得到一个无法推断(Ord a)错误?

时间:2012-10-21 23:15:52

标签: haskell

我试图找到元素总和最小的列表。:

shortest :: (Num a) => [[a]] -> [a]
shortest [] = []
shortest (x:xs) = if sum x < sum (shortest xs) then x else shortest xs

这给了我以下错误:

Could not deduce (Ord a) arising from a use of `<'
from the context (Eq a)
  bound by the type signature for shortest :: Eq a => [[a]] -> [a]
  at code.hs:(8,1)-(9,71)
Possible fix:
  add (Ord a) to the context of
    the type signature for shortest :: Eq a => [[a]] -> [a]
In the expression: sum x < sum (shortest xs)
In the expression:
  if sum x < sum (shortest xs) then x else shortest xs
In an equation for `shortest':
    shortest (x : xs)
      = if sum x < sum (shortest xs) then x else shortest xs

为什么没有功能类型检查?

2 个答案:

答案 0 :(得分:16)

此代码涉及两个类型类:NumOrd。注意 类型可以是成员Num而不是Ord,反之亦然。

sum的类型为Num a => [a] -> a,因此shortest的输入元素必须是Num的成员。您还可以执行以下操作 在你的代码中:

sum x < sum (shortest xs)

这意味着您在<上使用了运算符a,但在您的类型签名中,您并不要求aOrd的实例它定义了<

class Eq a => Ord a where
  compare :: a -> a -> Ordering
  (<) :: a -> a -> Bool
  ...

因此,您需要将该要求添加到您的类型签名中:

shortest :: (Ord a, Num a) => [[a]] -> [a]

或者您可以省略类型签名。

答案 1 :(得分:5)

Num不包含Ord,因此您在类型签名中缺少Ord a约束。它应该是

shortest :: (Num a, Ord a) => [[a]] -> [a]

您可以删除类型签名,GHC会为您推断。