如何解决列表理解的错误消息与地板浮点数和 lambda 函数
我正在学习 Haskell,但在列表理解方面有一些问题。 如果我定义一个函数来获取给定数字的除数列表,我会得到一个错误。
check n = [x | x <- [1..(floor (n/2))],mod n x == 0]
我不明白为什么会导致错误。如果我想生成一个从 1
到 n/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
因此需要同时是 RealFrac
和 Integral
。虽然从技术上讲我们可以制作这种类型,但没有多大意义。
发生这种情况的原因是因为使用了 mod :: Integral a => a -> a -> a
这要求 x
和 n
是相同的类型,并且 a
应该是Integral
类型类。
另一个问题是n/2
的使用,因为(/) :: Fractional a => a -> a -> a
要求n
和2
与n / 2
具有相同的类型,而{{1} } 的类型也应该是 n
的成员。更糟糕的是,我们使用 floor :: (RealFrac a,Integral b) => a -> b
强制 Fractional
(因此 n
也是如此)具有属于 x
类型类成员的类型。>
我们可以通过使用 div :: Integral a => a -> a -> a
来防止 RealFrac
和 Fractional
类型的约束。由于 RealFrac
已经要求 mod
具有属于 n
类型类成员的类型,因此这不会进一步限制类型:
Integral
例如打印:
check n = [x | x <- [1 .. div n 2],mod n x == 0]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。