如何最好地表示由输入更新的状态?
我模拟物理系统。它有状态(坐标,速度)。 状态通过从 stdin
中获取一些参数(力)进行模拟更新。每次模拟周期后结果都会被输出到 stdout
。
程序应在 N 个周期后停止。
我已经使用了 readIORef
和 writeIORef
但这很丑陋。
如何最好地表示由输入更新的状态?
我模拟物理系统。它有状态(坐标,速度)。 状态通过从 stdin
中获取一些参数(力)进行模拟更新。每次模拟周期后结果都会被输出到 stdout
。
程序应在 N 个周期后停止。
我已经使用了 readIORef
和 writeIORef
但这很丑陋。
import Control.Monad.State
-- Prerequisites:
data SimState -- coordinates & velocities.
data SimTVParams -- what's read from input. `instance Read`.
initialState :: SimState
simStep :: SimTVParams -> SimState -> SimState
simStateInfo :: SimState -> String
-- How to do the simulation:
main :: IO ()
main = interact $
unlines . map simStateInfo
. simulate initialState
. map read . lines
simulate :: SimState -> [SimTVParams] -> [SimState]
simulate iState = (`evalState` iState) . mapM (state . step)
where step params oldState = (newState, newState)
where newState = simStep params oldState
data Status = Status deriving (Show)
data Param = Param deriving (Read)
initialState :: Status
initialState = undefined
update :: Status -> Param -> Status
update = undefined
numCycles :: Int
numCycles = undefined
import Pipes
import qualified Pipes.Prelude as P
main = runEffect $
P.readLn >-> P.take numCycles >-> P.scan update initialState id >-> P.print
P.readLn
从标准输入读取输入参数。如果到达输入结束会停止执行。P.take numCycles
只允许最多 numCycles
个参数通过。P.scan
使用提供的初始状态和更新函数运行模拟,然后将每个中间状态向下游传递。P.print
打印出每个中间状态。pipes
库的信息,你可以阅读 官方 pipes
教程。
eof
而不是固定步数上更加自然。 - leftaroundabout