我是 Haskell 的初学者,用它解决了Project Euler的大约 50 个问题,但现在我被困在问题 66上。问题是编译后的代码 ( ghc -O2 --make problem66.hs
) 在 10-20 秒后占用了我机器的所有空闲内存。我的代码如下所示:
-- Project Euler, problem 66
diophantine x y d = x^2 - d*y^2 == 1
minimalsolution d = take 1 [(x, y, d) | y <- [2..],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
issquare x = (round $ sqrt $ fromIntegral x)^2 == x
main = do
print (map minimalsolution (filter (not . issquare) [1..1000]))
我有一种预感,问题出在列表理解中的无限列表中minimalsolution
。
我实际上认为,由于懒惰,Haskell 只会评估列表,直到它找到一个元素(因为take 1
)并在途中丢弃所有diophantine
评估为的元素False
。我错了吗?
有趣的是,我在 ghci 中没有看到这种行为。是因为 ghci 内部的处理速度太慢了,以至于我不得不等到我看到内存消耗爆炸 - 还是其他原因?
请不要剧透。我只想知道极端内存消耗的来源以及如何解决它。