我写了一个小的生命游戏程序,可以自动进行迭代。问题在于,每次迭代时,putStrLn函数的速度会明显变慢,我无法找出原因。以下是代码:
import Control.Concurrent
data CellState = Dead | Alive
data Position = Position Integer Integer
type Generation = Position -> CellState
is_alive :: CellState -> Bool
is_alive Alive = True
is_alive Dead = False
neighbors :: Position -> [Position]
neighbors (Position x y) =
[(Position (x-1) (y-1)), (Position x (y-1)), (Position (x+1) (y-1)), (Position (x+1) y),
(Position (x+1) (y+1)), (Position x (y+1)), (Position (x-1) (y+1)), (Position (x-1) y)]
alive_neighbors :: Generation -> Position -> Int
alive_neighbors generation position = length (filter is_alive (map generation (neighbors position)))
evolution :: Generation -> Generation
evolution generation position =
case (alive_neighbors generation position) of
2 -> if (is_alive (generation position)) then Alive else Dead
3 -> Alive
_ -> Dead
visualize_generation generation = map (visualize_line generation) [1..10]
visualize_line :: Generation -> Integer -> String
visualize_line generation y = concat (map (visualize_cell generation y) [1..10])
visualize_cell generation y x =
case (generation (Position x y)) of
Alive -> ['0']
Dead -> ['.']
{-
bar (Position 1 2) = Alive
bar (Position 2 3) = Alive
bar (Position 3 3) = Alive
bar (Position 3 2) = Alive
bar (Position 3 1) = Alive
bar (Position x y) = Dead
-}
bar (Position 1 3) = Alive
bar (Position 2 3) = Alive
bar (Position 3 3) = Alive
bar (Position x y) = Dead
life :: Generation -> IO ()
life bar_ = do cls
mapM_ putStrLn (visualize_generation bar_)
threadDelay 1000000
life (evolution bar_)
cls = putStr "\ESC[2J"
我最初认为每一代新的计算方式都会计算所有之前的计算方式,但似乎并非如此。如果是这样,我期望演化函数的计算时间会增加,而不是putStrLn函数打印得慢。有什么想法可以解释为什么每一代都会导致putStrLn函数变得如此缓慢吗?