1

我收到一个错误:

No instance for (Integral [t0])当我运行这个haskell代码时。

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

我哪里错了?

4

2 回答 2

6

问题是您正在尝试划分列表。尤其xs `div` 2是不正确的表达方式。

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

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

您可以通过查看以下类型来了解为什么会收到此确切错误消息div

div :: Integral i => i -> i -> i

这意味着给定类i中的某种类型Integral,您可以将其中的两个分开以获得第三个。由于事物列表不是积分类的一部分,因此您不能将它们分开,因此会出现错误。

如果div有一个具体的类型div :: Int -> Int -> Int,你会得到一个错误,告诉你它不能匹配预期的类型Int和实际的类型[t0]。但是,由于该类型实际上包含一个 variable i,所以错误有点复杂:因为它不在类中,所以[t0]不能是一个有效的类型来代替。iIntegral

于 2013-05-25T05:07:44.847 回答
6

你说的是:

给我一个a, b, 和的元组c

[ (a, b, c)

对于从到的值列表中的每个ab和:c1xs1

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

对于和 2xs2的商中的每个。xs1

, xs2 <- xs1 `div` 2
]

如果您编译时启用警告-Wall(显然,这种警告会非常有帮助,因为它可以直接指出您的问题。:set -Wallxsxs <- ...xsboomBangs xs = ...

由于xs1是函数的输入,因此您最终会得到如下类型:

(Integral [t]) => [t] -> [([t], [t], [t])]

也就是说,该函数接受一个xs1可以充当数字 ( (`div` 2)) 的列表 (),并为您返回一个此类列表的元组列表。即使您尝试将列表除以一个数字,GHC 也允许它并推断出更通用的类型,因为您可以为列表定义一个Integral实例。只有当您实际尝试在具体类型上使用该函数时,它才会发现您没有。写下类型签名可以帮助保持编译器的基础并为您提供更好的错误消息。

我只能猜你的意思是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]
]
于 2013-05-25T05:19:45.650 回答