Haskell列表推导式求约数及完美数筛选代码报错问题咨询
我来帮你排查这两段Haskell代码的问题,咱们一步步拆解:
问题1:约数函数check的类型不匹配错误
你写的check函数报错,核心原因是类型不兼容:
- 当
n是整数输入时,n/2会得到浮点数(比如5/2是2.5),floor处理后返回的是Integer类型; - 但列表推导式里的起始值
1是Int类型,Haskell是强类型语言,[1..x]要求上下界必须是同一种数值类型,所以这里触发了类型错误。
解决起来很简单,别用浮点数除法/,改用整数除法div——它直接返回整数结果,完全不需要转浮点数再取整:
check n = [x | x <- [1..n `div` 2], mod n x == 0]
这样[1..n div 2]的上下界都是同类型整数,列表推导式就能正常运行了。
问题2:完美数筛选代码的双重错误
你这段完美数的代码有两个明显问题:
- lambda表达式语法写错了:
filter ( -> ...)这里箭头前面缺了参数名,而且符号用错了——应该是\t ->(注意是反斜杠加参数名t,不是空格); - 重复了第一个问题的类型不匹配:
f n里的floor (n/2)还是会导致类型冲突,同样要换成整数除法div。
修正后的完整代码如下,还可以把foldr (+) 0换成更简洁的sum函数:
f n = [x | x <- [1..n `div` 2], mod n x == 0] -- 先正确生成约数列表 main = print $ filter (\t -> sum (f t) == t) [2..100]
运行这段代码,就能得到2到100之间的完美数:[6,28]。
内容的提问来源于stack exchange,提问作者Herakles
相关产品推荐
相关产品推荐

