Haskell错误“因使用...而没有(Eq a0)的实例”

时间:2013-12-02 23:59:55

标签: haskell

任何人都知道为什么以下代码在“matchListWith eq [] []”中失败了?

- failure.hs

matchListWith :: (Eq a) => (a -> a -> Bool) -> [a] -> [a] -> Bool
matchListWith f (x:xs) (y:ys) = (f x y) && (matchListWith f xs ys)
matchListWith _ []     []     = True
matchListWith _ _      _      = False

eq :: (Eq a) => a -> a -> Bool
eq a b = (a == b)

main = do
   print (matchListWith eq [1, 3] [1, 3])
   print (matchListWith eq [1, 3] [1])
   print (matchListWith eq [1] [1, 3])
   print (matchListWith eq [3, 1] [1, 3])
   print (matchListWith eq [1] [])
   print (matchListWith eq [] [])

- eof

错误是:

failure.hs:16:11:
    No instance for (Eq a0) arising from a use of `matchListWith'
    The type variable `a0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in `GHC.Real'
      instance Eq () -- Defined in `GHC.Classes'
      instance (Eq a, Eq b) => Eq (a, b) -- Defined in `GHC.Classes'
      ...plus 22 others
    In the first argument of `print', namely `(matchListWith eq [] [])'
    In a stmt of a 'do' block: print (matchListWith eq [] [])
    In the expression:
      do { print (matchListWith eq [1, 3] [1, 3]);
           print (matchListWith eq [1, 3] [1]);
           print (matchListWith eq [1] [1, 3]);
           print (matchListWith eq [3, 1] [1, 3]);
           .... }

奇怪的是,如果我在GHCi中加载两个函数matchListWith eq [] [], 工作得很好。

*Main> matchListWith eq [] []
True
*Main> 

我正在使用GHC版本7.6.3。

1 个答案:

答案 0 :(得分:3)

原因是当你打电话时

matchListWith eq [] []

编译器不知道它是什么类型的列表。它只知道它是[a]类型的值,但是它没有对它Eq a =>约束。将其更改为

matchListWith eq [] ([] :: [Int])

它应该编译


有时你必须给GHC一些帮助才能知道它正在使用什么类型。如果你试过

就会一样
myFunc :: m Int
myFunc = do
    let x = 1
        y = 2
    return $ x + y

这不会编译,因为编译器没有被告知mMonad,你必须添加额外的上下文

myFunc :: Monad m => m Int

让它发挥作用。

它在GHCi中工作的原因是因为有更多急切的类型推断。为了使交互式部件更易于使用,GHCi通常会选择比GHC更具体的类型。