Я хотел бы в целом выяснить, как использовать изменяемое состояние при вычислении ленивых списков.
Например, вот наивное решето Эратосфена, реализованное с использованием изменяемого массива(источник):
import Control.Monad.ST
import Data.Array.ST
import Data.Array.Unboxed
import Control.Monad
import Data.List
prime :: Int -> UArray Int Bool
prime n = runSTUArray $ do
arr <- newArray ( 2, n ) True :: ST s ( STUArray s Int Bool )
forM_ ( takeWhile ( \x -> x*x <= n ) [ 2.. n ] ) $ \i -> do
ai <- readArray arr i
when ( ai ) $ forM_ [ i^2, i^2 + i.. n ] $ \j -> do
writeArray arr j False
-- yield i ???
prime n
возвращает массив логических значений, обозначающих, какие числа являются простыми.
Есть ли способ использовать этот подход для создания ленивого -списка этих простых чисел? Это все равно, что добавить yield i
сразу после оператора writeArray
.