列表理解的错误消息与地板浮点数和 lambda 函数

问题描述

我正在学习 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 :: (RealFrac a,Integral a) => a -> [a]

输入(和输出)的类型 a 因此需要同时是 RealFracIntegral。虽然从技术上讲我们可以制作这种类型,但没有多大意义。

发生这种情况的原因是因为使用了 mod :: Integral a => a -> a -> a 这要求 xn 是相同的类型,并且 a 应该是Integral 类型类。

另一个问题是n/2的使用,因为(/) :: Fractional a => a -> a -> a要求n2n / 2具有相同的类型,而{{1} } 的类型也应该是 n 的成员。更糟糕的是,我们使用 floor :: (RealFrac a,Integral b) => a -> b 强制 Fractional(因此 n 也是如此)具有属于 x 类型类成员的类型。>

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

Integral

例如打印:

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...