Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
模拟用Haskell单子_Haskell - Fatal编程技术网

模拟用Haskell单子

模拟用Haskell单子,haskell,Haskell,表示由输入更新的状态的最佳方式是什么 我模拟物理系统。它有状态(坐标、速度)。状态通过从stdin获取一些参数(力)的模拟进行更新。每个模拟循环后,结果进入标准输出 程序应在N个周期后停止 我已经用readIORef和writeIORef完成了,但这很难看。一个简单的方法是沿着一个懒惰的(可能是无限的)列表,而不是执行任何显式IO import Control.Monad.State -- Prerequisites: data SimState -- coordinates &am

表示由输入更新的状态的最佳方式是什么

我模拟物理系统。它有状态(坐标、速度)。状态通过从
stdin
获取一些参数(力)的模拟进行更新。每个模拟循环后,结果进入标准输出

程序应在N个周期后停止


我已经用
readIORef
writeIORef
完成了,但这很难看。

一个简单的方法是沿着一个懒惰的(可能是无限的)列表,而不是执行任何显式IO

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
    打印每个中间状态

要了解有关管道库的更多信息,请阅读。

谢谢。N步后不会退出。但是我可以通过stdin通过sh中的head-n来完成这个。对于此类任务,停止执行
eof
而不是固定数量的步骤要自然得多。