haskell - 带 fclabel 的 STM

标签 haskell concurrency monads stm

我构建了一个小型游戏引擎来管理方 block (目前用于玩康威生命游戏)。所有数据均通过fclabels的镜头访问和状态。该引擎将用户输入和图形渲染(通常的游戏循环)结合起来。

帧之间的计算有时可能会很慢且执行时间较长。所以我想使用并发来管理方 block ,使用 STMTVar .

我的数据目前表示如下:

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(获取将涉及 readTVar,放置将涉及 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)

其中 State 为 Control.Monad.State,Total 为 Data.Label.Total。

但是 State.gets 采用纯函数,因此您将无法创建与 gets 一起使用的镜头。

关于haskell - 带 fclabel 的 STM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31861580/

相关文章:

java - 获取 random.NextBoolean() 的结果并在进一步的 if 语句中使用它

java - 与 ThreadLocal 同步还是 InheritableThreadLocal?

java - 创建 SingleBlockingQueue 同步器

ocaml - 在 OCaml 中做符号

arrays - Haskell 中如何实现可变数组?

haskell - 如何在 Haskell 中过滤无限列表

c++ - 可以在 Haskell 中模拟 'correspond' 类型的 C++ 结构模式(模板特化)吗?

haskell - Bifunctor 实例定义上的类型签名不匹配

haskell - 如何处理添加新包依赖项的功能请求

haskell - 对调用者来说看起来很纯粹但内部使用突变的函数