带有 fclabels 的 STM
STM with fclabels
我构建了一个小型游戏引擎来管理方块板(目前用于玩康威的人生游戏)。所有数据都通过来自 fclabels 和 State 的镜头访问。该引擎结合了用户输入和图形渲染(通常的游戏循环)。
帧之间的计算有时会很慢并且执行时间很长。所以我想使用并发来管理方块,使用 STM's 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 versions of labels。我在我的 monad 中使用 Getters & Setters。
我想知道是否有办法以某种方式编写新标签,这些标签的行为如下:
gets :: MonadState f m => Lens (->) f o -> m o
…
puts :: MonadState f m => Lens (->) f o -> o -> m ()
但这会处理 STM(gets 会涉及 readTVar,puts 会涉及 writeTvar,等等)。
如果我没理解错的话,你想定义一个镜头tlens
s.t.:
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
的定义是(link)是:
gets lens = State.gets (Total.get lens)
其中状态为 Control.Monad.State,总计为 Data.Label.Total。
但是 State.gets
需要一个纯函数,所以你还是不能创建一个可以与 gets
一起使用的镜头。
我构建了一个小型游戏引擎来管理方块板(目前用于玩康威的人生游戏)。所有数据都通过来自 fclabels 和 State 的镜头访问。该引擎结合了用户输入和图形渲染(通常的游戏循环)。
帧之间的计算有时会很慢并且执行时间很长。所以我想使用并发来管理方块,使用 STM's 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 versions of labels。我在我的 monad 中使用 Getters & Setters。
我想知道是否有办法以某种方式编写新标签,这些标签的行为如下:
gets :: MonadState f m => Lens (->) f o -> m o
…
puts :: MonadState f m => Lens (->) f o -> o -> m ()
但这会处理 STM(gets 会涉及 readTVar,puts 会涉及 writeTvar,等等)。
如果我没理解错的话,你想定义一个镜头tlens
s.t.:
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
的定义是(link)是:
gets lens = State.gets (Total.get lens)
其中状态为 Control.Monad.State,总计为 Data.Label.Total。
但是 State.gets
需要一个纯函数,所以你还是不能创建一个可以与 gets
一起使用的镜头。