Haskell 带FCM标签的STM
我建立了一个小游戏引擎来管理一块方格板(目前用于玩康威的生活游戏)。所有数据都是通过镜头从和状态访问的。该引擎将用户输入和图形渲染(通常的游戏循环)结合起来 帧之间的计算有时执行起来很慢,而且很长。所以我想使用并发来管理正方形,使用的是 我的数据当前表示如下:Haskell 带FCM标签的STM,haskell,concurrency,monads,stm,Haskell,Concurrency,Monads,Stm,我建立了一个小游戏引擎来管理一块方格板(目前用于玩康威的生活游戏)。所有数据都是通过镜头从和状态访问的。该引擎将用户输入和图形渲染(通常的游戏循环)结合起来 帧之间的计算有时执行起来很慢,而且很长。所以我想使用并发来管理正方形,使用的是 我的数据当前表示如下: data World = World { … -- window configuration, not important , _squares :: TVar [Square] } mkLabels [''World]
data World = World {
… -- window configuration, not important
, _squares :: TVar [Square]
}
mkLabels [''World] -- creates labels, similar to mkLenses
我的函数在Monad游戏中运行,其定义如下:
type Game a = StateT World IO a
使用。我在monad中使用getter和setter
我想知道是否有一种方法可以以某种方式写出如下行为的新标签:
gets :: MonadState f m => Lens (->) f o -> m o
…
puts :: MonadState f m => Lens (->) f o -> o -> m ()
但这需要处理STM(GET将涉及readTVar,puts将涉及writeTvar等)。如果我理解正确,您需要定义一个镜头
tlens
s.t:
gets tlens
同:
do tvar <- gets squares
sqs <- liftIO $ atomically $ readTVar tvar
return sqs
do tvar <- gets squares
liftIO $ atomically $ writeTVar tvar sqs
我认为可以通过查看获取的类型来回答这个问题:
gets :: MonadState f m => Lens (->) f o -> m o
透镜参数是纯的,不是一元的。要获取TVar的内容,需要在IO monad中运行代码
此外,Data.Label.Monadic中的定义为:
其中State为Control.Monad.State,Total为Data.Label.Total
但是,State.gets
需要一个纯函数,所以在查看并发性之前,您可能需要先查找瓶颈,然后再创建一个可以与gets
一起使用的镜头。如果你只是在做生活游戏,你应该可以很容易地得到几百次更新每秒即使是在普通的硬件上。@Cubic生活游戏目前只用于测试引擎。这不是优化问题,但能够在与计算游戏机制相同的时间内处理输入。频率也取决于棋盘的大小。我知道这一点,我想我可以通过使用。它使用箭头,箭头(多少?)与单子有关。我应该试一试,还是我只是在胡说八道?我还不太明白这些要点,但它们看起来确实是可扩展的。看看这个答案:-它甚至有一个STM示例。
gets lens = State.gets (Total.get lens)