注意:可能有一些拼写错误(大写字母等),因为我的无线网卡在我的电脑上坏了,我不能在这个上安装haskell,所以我重新输入代码(我没有记忆棒xD)
我一直在使用
Config line values 2 2
定义一个Config,但我不喜欢这个函数'start'。任何需要f - > f工作得很好但是......
data Config = Config {
line :: Line,
nums :: [Nums],
indent :: Indent,
run :: Run
} deriving (Eq, Show)
class (Result f) => Test f where
start :: Line -> [Nums] -> f
instance Test Config where
start line nums = Config line nums 0 0
如果我跑
> start 2 [0,0,0]
应返回
> Config 2 [0,0,0] 0 0
我收到错误:
Ambiguous type variable `f0' in the constraint:
(Test f0) arising from a use of `start'
Probable fix: add a type signature that fixes these type variable(s)
正在运行
> :t Config 2 [0,0,0] 0 0
给出
> Config 2 [0,0,0] 0 0 :: Config
这是正确的
答案 0 :(得分:4)
嗯,正如消息所说的那样,
start 2 [0,0,0]
可以包含任何类型,即Test
的实例。没有你告诉它,编译器无法直接使用类型签名
> start 2 [0,0,0] :: Config
应该没有问题,或者提供可以推断出类型的上下文,
> indent $ start 2 [0,0,0]
也应该有效,因为类型现在可以通过使用indent
结果的start
类型推断。
您可能希望编译器选择类型Config
,因为目前这是Test
的唯一实例。但是编译器从不选择实例,因为它不知道其他实例,因为当其他实例添加到不同的模块时,它可能会破坏代码。
答案 1 :(得分:1)
问题是,在构造时,表达式start 2 [0,0,0,0]
可以返回属于类Test
的任何类型。在该实例中,系统无法返回Config
。如果你明确地施展它,即
start 2 [0,0,0] :: Config
应该有效。