9

Haskell でかなり大きいが有限のデカルト積を生成したいと思います。これを反復する必要があります (平均場モデルの分配関数を考えてください)。自然なことはsequence、次のように を使用します。

l = sequence $ replicate n [0,1,2]

残念ながら、大きな のn場合、これはメモリに収まらず、たとえば要求するとすぐにヒープが不足しlength lます。同じことを怠惰に行う方法が必要です。このように、私は最終的に3進数の算術を「再発見」しました。

nextConfig []     = []
nextConfig (0:xs) = 1:xs
nextConfig (1:xs) = 2:xs
nextConfig (2:xs) = 0:(nextConfig xs)

ll = take (3^n) $ iterate nextConfig $ replicate n 0

(これは機能します)しかし、車輪を再発明したような気がします。さらに、あまりにも具体的です. 製品を生成するためのより良い怠惰な方法は何でしょうか?

4

2 に答える 2

8

よりメモリフレンドリーな方法は、シーケンスと比較して逆の順序でバインドすることによって得られます。

foo 0 _ = [[]]
foo k xs = [h:t | t <- foo (k-1) xs, h <- xs]

共有が少ないため遅くなりますが、メモリが問題であるため、おそらくそれで十分です。

于 2012-04-12T12:53:52.183 に答える