约束中的模糊类型变量`f0':Haskell

时间:2012-05-18 19:13:47

标签: haskell

注意:可能有一些拼写错误(大写字母等),因为我的无线网卡在我的电脑上坏了,我不能在这个上安装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 

这是正确的

2 个答案:

答案 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

应该有效。