List 在Haskell中计算3和5的倍数之和时出现内存不足错误
这是我的代码:List 在Haskell中计算3和5的倍数之和时出现内存不足错误,list,haskell,recursion,sum,out-of-memory,List,Haskell,Recursion,Sum,Out Of Memory,这是我的代码: import Data.Bits main = print . sum . takeWhile( < 200000) $ multSum 999 multSum m = 3 : multiples [6..m] where multiples (p:xs) | ((p `mod` 3 == 0) || (p `mod` 5 == 0)) = p : multiples([p..m]) | otherwise = p : xs
import Data.Bits
main = print . sum . takeWhile( < 200000) $ multSum 999
multSum m = 3 : multiples [6..m] where
multiples (p:xs)
| ((p `mod` 3 == 0) || (p `mod` 5 == 0)) = p : multiples([p..m])
| otherwise = p : xs
导入数据.位
main=打印。总和takeWhile(<200000)$multSum 999
multSum m=3:倍数[6..m]其中
倍数(p:xs)
|((p`mod`3==0)|(p`mod`5==0))=p:multiples([p..m])
|否则=p:xs
错误:内存不足(请求的1048576字节)
我哪里做错了?
multSum
没有做你认为应该做的事。尝试直接调试它:
*Main> take 20 $ multSum 999
[3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]
multSum
没有做你认为应该做的事。尝试直接调试它:
*Main> take 20 $ multSum 999
[3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]
multSum
为所有参数返回无限列表[3,6,6,6,6…]
,因此它永远不会超过200000,因此无法打印您请求的总和。multSum
为所有参数返回无限列表[3,6,6,6,6…]
,因此,它永远不会超过200000,因此无法打印您请求的金额。试试看
mults35 m = multiples [3..m] .....
............
....| ...... = p : multiples xs
... | otherwise = multiples xs
你还有一件事要补充。试试这个,你就会看到。试试
mults35 m = multiples [3..m] .....
............
....| ...... = p : multiples xs
... | otherwise = multiples xs
你还有一件事要补充。试试这个,你会发现。我得到的错误是:prob1:prob1.hs:(6,5)-(8,33):函数中的非穷举模式multiples@Hick确切地您的定义是:
倍数(p:xs)=……
。也就是说,它接收非空列表,其中头元素p
,其余元素xs
。但如果它收到非空列表,[]
,该怎么办?这个子句是在你的程序中定义的吗?如果没有,请添加它@您可以这样添加新子句:multiples[]=…
它应该返回与前一个子句相同类型的结果。它的返回值是p:…
,即它是一个列表。因此,新子句也必须返回一个列表。在这种情况下,最后一种情况不应该是:p==m=p:multiples 0,即不再需要遍历数组的情况吗?如果没有,那我就完全糊涂了。@Hick“倍数”收到一个列表。它要么是非空列表(p:xs)
,要么是空列表[]
。但是,我们知道它在消耗什么列表-我们给了它那个列表-它是列表[3..m]
。因此,是的,该列表中的最后一个元素将是p
,此时的列表将是一个单元素列表(即,其中只有一个元素)(p:xs)
,其中xs=[]
。当我们检测到我们也在最后一个元素上时,我们可以停止处理,是的,这是另一种编码方式。这样我们就永远不会碰到一个空的列表案例。因此,我们必须在非空条款中添加一个新的子条款,在这两个子条款之上。(续)我得到的错误是:prob1:prob1.hs:(6,5)-(8,33):函数中的非穷举模式multiples@Hick没错!您的定义是:multiples(p:xs)=…
。也就是说,它接收非空列表,头元素p
,其余元素xs
。但是如果它接收非空列表,[]
?该子句是否定义在程序中的某个地方?如果没有,请添加它!@Hick您添加新子句时,会这样:倍数[]=…
它应该返回与前一个子句相同类型的结果。它的返回值是p:…
,即它是一个列表。因此新子句也必须返回一个列表。在这种情况下,最后一个情况不应该是:p==m=p:将没有数组可遍历的结果乘以0吗?如果不是,那么我完全糊涂了。@Hick“multiples”接收一个列表。它要么是一个非空列表(p:xs)
,要么是一个空列表[]
。但是,我们知道它在消耗什么列表-我们给了它那个列表-它是一个列表[3..m]
。因此,是的,该列表中的最后一个元素将是p
,此时的列表将是一个单例列表(也就是说,只有一个元素在里面)(p:xs)
其中xs=[]
。当我们检测到我们也在最后一个元素上时,我们可以停止处理,是的,这是另一种编码方式。这样我们就永远不会碰到空的列表大小写。因此,我们必须在非空子句中添加一个新的子子句,在这两个元素之上。(续)