我收到了一个错误:
当我运行这个haskell代码时, No instance for (Integral [t0])
。
boomBangs xs = [(a,b,c) |a<-[1..xs],b<-[1..xs],c<-[1..xs], xs <- xs `div` 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)
你说的是:
给我一个
a
,b
和c
的元组:[ (a, b, c)
对于
a
到b
的值列表中的每个c
,1
和xs1
:| 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}}