如何为Haskell的集合构建器表示法指定类型?

时间:2010-07-09 08:34:48

标签: list haskell

具体来说,我想做这样的事情:

myfunc:: [(Integer, Integer)]
myfunc = [(x^2 - y^2, 2 * x * y) | x <- [1..], y <- [1.. (x-1)]]

当我尝试通过ghci加载时,我得到了

    Warning: Defaulting the following constraint(s) to type `Integer'
         `Integral t' arising from a use of `^' at myfunc.hs:76:20-22

所以我知道x显然应该是Integer,我该如何继续让Haskell知道我想要的东西?

2 个答案:

答案 0 :(得分:11)

这里的问题是^的类型为(Num a, Integral b) => a -> b -> a,因此^的第二个参数可以是任何整数类型。因为结果类型是Integer Haskell知道a是Integer,但它对b一无所知。不知道该怎么做,它默认为Integer并产生警告。由于在这种情况下完全没问题,您可以忽略或禁用警告。

但是,如果您更愿意添加类型注释以明确表示您希望右操作数具有Integer类型,则可以这样执行:

(x^(2::Integer) - y^(2::Integer), 2 * x * y)

作为旁注:[]创建一个列表,而不是一个集合。

答案 1 :(得分:2)

更具体地说,警告是关于2,而不是关于x(或y)。

KennyTM建议或将其写为(x x - y y,...)将使警告消失。

另外,请注意这是一个警告 - 您的系统似乎设置为在程序中提供尽可能多的警告(“-Wall”),这是一个很好的方法来控制编译器认为你的'干嘛因为它只是一个警告,你可以随意忽略它;它会做你想要的。为了更好地学习系统,最好让人们了解警告出现的原因。