STM与fclabels
我建立了一个小型游戏引擎来管理一块广场(目前用于播放康威的生活游戏)。 所有的数据都可以通过fclabels和State的镜头进行访问。 引擎结合用户输入和图形渲染(通常的游戏循环)。
帧之间的计算有时可能很慢并且需要很长时间才能执行。 所以我想使用并发性来管理广场,使用STM的TVar。
我的数据目前是这样表示的:
data World = World {
… -- window configuration, not important
, _squares :: TVar [Square]
}
mkLabels [''World] -- creates labels, similar to mkLenses
我的函数在Game Monad中运行,其定义如下:
type Game a = StateT World IO a
使用标签的monadic版本。 我在我的monad中使用了Getters&Setters。
我想知道是否有办法以某种方式编写新行为如此的标签:
gets :: MonadState f m => Lens (->) f o -> m o
…
puts :: MonadState f m => Lens (->) f o -> o -> m ()
但是,照顾STM(获取将涉及readTVar,put将涉及writeTvar等)。
如果我正确理解你,你想要定义一个镜头tlens
st:
gets tlens
是相同的:
do tvar <- gets squares
sqs <- liftIO $ atomically $ readTVar tvar
return sqs
并且puts tlens sqs
与以下相同:
do tvar <- gets squares
liftIO $ atomically $ writeTVar tvar sqs
我认为这可以通过查看gets
类型来回答:
gets :: MonadState f m => Lens (->) f o -> m o
镜头参数是纯粹的而不是单一的。 要了解TVar的内容,您需要在IO-monad中运行代码。
而且,Data.Label.Monadic中gets
的定义是(链接)是:
gets lens = State.gets (Total.get lens)
状态是Control.Monad.State和Total是Data.Label.Total。
但State.gets
需要一个纯粹的功能,所以你又不是要能够创建一个镜头,将与gets
。
上一篇: STM with fclabels