円周率を近似するコードです。

main :: IO ()
main = do
    let points = [(x,y) | x<-range 10000, y<-range 10000]
    let all = length $ points
    let hit = length $ filter ((<= 1) . distance) points
    putStrLn $ show $ (fromIntegral hit * 4) / (fromIntegral all)
    where
        range n = (map (/ n) [0 .. n])
        distance (a,b) = sqrt(a*a+b*b)

このコードを実行するとメモリが大量に消費され、システムが停止します。何か問題があるようです。

しかし、hit だけを評価、あるいは all だけを評価すると、このコードは動作します。

main :: IO ()
main = do
    let points = [(x,y) | x<-range 10000, y<-range 10000]
    let all = length $ points
    let hit = length $ filter ((<= 1) . distance) points
    putStrLn $ show hit
    --putStrLn $ show all -- このコメントアウトを外して hit と all 両方を表示しようとするとスペースリークが発生する
    where
        range n = (map (/ n) [0 .. n])
        distance (a,b) = sqrt(a*a+b*b)

これは何が起きているのでしょうか?