带有底浮点数和 lambda 函数的列表理解的错误消息

error message by list comprehension with floored float numbers and in lambda functions

我正在学习 Haskell,但在列表理解方面存在一些问题。 如果我定义一个函数来获取给定数字的除数列表,则会出现错误。

check n = [x | x <- [1..(floor (n/2))], mod n x == 0]

我不明白为什么它会导致错误。如果我想生成一个从 1n/2 的列表,我可以使用 [1..(floor (n/2))] 来完成,但如果我在列表理解中这样做则不行。

我尝试了另一种方法,但我也遇到了错误(在这段代码中我想得到所有所谓的“完美数字”)

f n = [1..(floor (n/2))]

main = print $ filter (\t -> foldr (+) 0 (f t) == t) [2..100]

一般开始写签名比较好。虽然通常不需要签名,但可以更轻松地调试单个函数。

您的 check 函数的签名是:

check :: (<strong>RealFrac a, Integral a</strong>) => a -> [a]

输入(和输出)的类型 a 因此需要既是 RealFrac 又是 Integral。虽然从技术上讲我们可以做出这样的类型,但意义不大。

发生这种情况的原因是因为使用 mod :: Integral a => a -> a -> a 这要求 xn 都是同一类型,而 a 应该是Integral 类型类的成员。

另一个问题是 n/2 的使用,因为 (/) :: Fractional a => a -> a -> a requires that n and 2 have the same type as n / 2, and n should also be of a type that is a member of Fractional. To make matters even worse, we use floor :: (RealFrac a, Integral b) => a -> b 强制 n(因此 x 也)有一个类型是RealFrac 类型类。

我们可以通过使用 div :: Integral a => a -> a -> a 来防止 FractionalRealFrac 类型约束。由于 mod 已经要求 n 具有属于 Integral 类型类成员的类型,因此这不会进一步限制类型:

check n = [x | x <- [1 .. <strong>div n 2</strong>], mod n x == 0]

例如打印:

Prelude> print (check 5)
[1]
Prelude> print (check 17)
[1]
Prelude> print (check 18)
[1,2,3,6,9]