STM with fclabels

I built a small game engine to manage a board of squares (currently used for playing a Conway's game of life). All the data is accessed throught lenses from fclabels and State. The engine couples user input and graphic rendering (usual game loop).

The computations between frames can sometimes be slow and long to execute. So I would like to use concurrency to manage the squares, using STM's TVar.

My data is currently represented like this:

data World = World {
    … -- window configuration, not important
    , _squares :: TVar [Square]
}

mkLabels [''World] -- creates labels, similar to mkLenses

My functions run in the Game Monad, which is defined as follow:

type Game a = StateT World IO a

Using the monadic versions of labels. I use Getters & Setters inside my monad.

I would like to know if there is a way to somehow write new labels that behave like these:

gets :: MonadState f m => Lens (->) f o -> m o 
…
puts :: MonadState f m => Lens (->) f o -> o -> m () 

But that takes care of STM (gets would involve readTVar, puts would involve writeTvar, etc.).


If I understand you correctly, you want to define a lens tlens st:

gets tlens

is the same as:

do tvar <- gets squares
   sqs <- liftIO $ atomically $ readTVar tvar
   return sqs

and where puts tlens sqs is the same as:

do tvar <- gets squares
   liftIO $ atomically $ writeTVar tvar sqs 

I think this can be answered by looking at the type of gets :

gets :: MonadState f m => Lens (->) f o -> m o

The lens parameter is pure and not monadic. To get at the contents of the TVar you'll need to run code in the IO-monad.

Moreover, the definition of gets in Data.Label.Monadic is (link) is:

gets lens = State.gets (Total.get lens)

where State is Control.Monad.State and Total is Data.Label.Total.

But State.gets takes a pure function, so again you're not going to be able to create a lens which will work with gets .

链接地址: http://www.djcxy.com/p/58768.html

上一篇: 如何在文本中表示和跟踪可变状态

下一篇: STM与fclabels