Haskell类函数:非常混乱的错误

时间:2015-08-31 00:43:58

标签: haskell

我的代码中有一个非常令人困惑的错误。我正在使用Data.Aeson包。我不认为这是包的错误。

class ToArrayFormat a where

    getObjects :: (ToJSON b) => a -> b

    toArrayFormat :: a -> Value
    toArrayFormat a = toJSON $ getObjects a

这段代码无法使用错误消息进行编译:

    Could not deduce (ToJSON s0) arising from a use of ‘toJSON’
from the context (ToArrayFormat a)
  bound by the class declaration for ‘ToArrayFormat’
  at <interactive>:(103,1)-(108,43)
The type variable ‘s0’ is ambiguous
In the expression: toJSON
In the expression: toJSON $ getObjects a
In an equation for ‘toArrayFormat’:
    toArrayFormat a = toJSON $ getObjects a

我现在很困惑。 getObjects会返回ToJSON b个实例,toJSON可以使用toArrayFormat。你不能从我的b定义中推断出getObjects的实例吗?为什么说ToJSON s0含糊不清?

1 个答案:

答案 0 :(得分:7)

关键是这一部分:

The type variable ‘s0’ is ambiguous

请注意,toJSON的类型为:

toJSON :: ToJSON b => b -> Value

此外,此声明:

getObjects :: (ToJSON b) => a -> b

表示getObjects可以将a转换为b类中的任何类型ToJSON。例如,如果blaha类型的值,您可以合法地要求:

getObjects blah :: Int
getObjects blah :: String
getObjects blah :: Char

并将blah转换为Int,String或Char,因为所有这些都在ToJSON类中。这可能不是你想到的,也不是你getObjects函数的作用。

要理解错误消息,问题是在表达式toJSON $ getObjects a中,GHC不知道如何键入getObjects b - ToJSON类的哪个成员应该是 - 一个Int?,String?,Char ?,其他一些类型?

您可以指定如下具体类型:

toArrayFormat a = toJSON $ (getObjects a :: Char)

但是,就像我说的那样,这可能不是你的想法。