我的代码中有一个非常令人困惑的错误。我正在使用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
含糊不清?
答案 0 :(得分:7)
关键是这一部分:
The type variable ‘s0’ is ambiguous
请注意,toJSON
的类型为:
toJSON :: ToJSON b => b -> Value
此外,此声明:
getObjects :: (ToJSON b) => a -> b
表示getObjects
可以将a
转换为b
类中的任何类型ToJSON
。例如,如果blah
是a
类型的值,您可以合法地要求:
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)
但是,就像我说的那样,这可能不是你的想法。