列表理解需要太多的记忆

Joh*_*s P 5 haskell list-comprehension lazy-evaluation

我是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]))
Run Code Online (Sandbox Code Playgroud)

我有一种预感,问题在于列表理解中的无限列表minimalsolution.

我实际上认为,由于懒惰,Haskell只会评估列表,直到它找到一个元素(因为take 1)并且在路上丢弃diophantine评估的所有内容False.我错了吗?

有趣的是,我没有在ghci中看到这种行为.是因为ghci中的处理速度慢得多,我只能等到看到内存消耗爆炸 - 或者是其他什么?

请不要剧透.我想知道的是极端内存消耗的来源以及我如何解决它.

Joh*_*s P 1

不管怎样,我在 6 年后测试了这个,这个问题不再出现。GHC 8.6.5 的内存消耗仍然非常低。我认为这确实是编译器中的一个问题,并且已在某个时候得到修复。