Haskell代码中没有(Integral [t0])错误的实例

时间:2013-05-25 05:02:45

标签: haskell

我收到了一个错误:

当我运行这个haskell代码时,

No instance for (Integral [t0])

boomBangs xs = [(a,b,c) |a<-[1..xs],b<-[1..xs],c<-[1..xs], xs <- xs `div` 2]

我哪里错了?

2 个答案:

答案 0 :(得分:6)

问题是你正试图划分一个清单。特别是,xs `div` 2是不正确的表达。

你可以从错误消息中得到这个:它抱怨[t0]的行为不像整数(例如它不在Integral类中)。 [t0]只是一个列表 - t0是小写的,是一个类型变量,可以重新识别任何类型。

由于东西的列表不是数字,我们真的不知道如何划分它们。

通过查看div

的类型,您可以了解收到此确切错误消息的原因
div :: Integral i => i -> i -> i

所有这些意味着,在i类中给定某种类型Integral,您可以将它们中的两个划分为第三个。由于事物列表不是整数类的一部分,因此不能将它们分开,因此会出错。

如果div具有类似div :: Int -> Int -> Int的具体类型,则会收到错误消息,告知您它与预期类型Int与实际类型[t0]不匹配。但是,由于类型实际上包含变量i,因此错误有点复杂:[t0]不能用作i的有效类型,因为它不在Integral中{1}}上课。

答案 1 :(得分:6)

你说的是:

  

给我一​​个abc的元组:

[ (a, b, c)
     

对于ab的值列表中的每个c1xs1

| a <- [1..xs1]
, b <- [1..xs1]
, c <- [1..xs1]
     

对于xs2和2。

的商中的每个xs1
, xs2 <- xs1 `div` 2
]

如果您在启用警告(-Wall)的情况下进行编译或在GHCi(:set -Wall)中启用它们,那么您会收到xs xs <- ...阴影中的警告xs中的boomBangs xs = ...,以及未使用的xs1。显然,这种警告可能非常有用,因为它指出了你的问题。

由于(Integral [t]) => [t] -> [([t], [t], [t])] 是您的函数的输入,因此最终得到如下类型:

xs1

这就是说该函数采用可以作为数字((`div` 2))的列表(Integral)并返回这些列表的元组列表。即使您尝试按列号划分列表,GHC也允许它并推断出更通用的类型,因为可以为列表定义boomBangs实例。它只发现当你实际尝试在具体类型上使用函数时,你还没有。写下类型签名有助于使编译器保持接地并为您提供更好的错误消息。

我只能猜测你的意思是Integral t => [t] -> [(t, t, t)] 有类似的类型:

[Int] -> [(Int, Int, Int)]

或者只是:

[ (a, b, c)
| x <- xs
, a <- [1..x `div` 2]
, b <- [1..x `div` 2]
, c <- [1..x `div` 2]
]

在这种情况下,你可能会想到这样的事情:

{{1}}