1

注意:可能有一些拼写错误(大写字母等),因为我的无线网卡在我的电脑上坏了,我无法在这个上安装 haskell,所以我重新输入代码(而且我没有记忆棒 xD)

我一直在使用
Config line values 2 2 定义一个配置,但我只是不喜欢这个函数'开始'。任何需要 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 

哪个是对的

4

2 回答 2

4

嗯,正如消息所说,

start 2 [0,0,0]

可以具有任何类型,它是 的实例Test。编译器无法在没有你告诉它的情况下找到它,或者直接使用类型签名,

> start 2 [0,0,0] :: Config

应该可以毫无问题地工作,或者通过提供可以推断类型的上下文,

> indent $ start 2 [0,0,0]

也应该可以工作,因为现在可以通过indent使用start.

您可能希望编译器选择类型Config,因为目前,这是Test. 但是编译器从不选择一个实例,因为它不知道其他实例,因为当其他实例添加到不同的模块中时,这可能会破坏代码。

于 2012-05-18T19:38:19.660 回答
1

问题是,在构造时,表达式start 2 [0,0,0,0]可以返回属于 class的任何Test类型。在那种情况下,您希望它返回一个Config. 如果你明确地投射它,即

start 2 [0,0,0] :: Config

那应该行得通。

于 2012-05-18T19:38:10.743 回答