I'm trying to build my own project upon an existing project called "GLFW-b-Demo".
Its apparently using something called "RWST" to simulate an environment and state:
data Env = Env
{ envEventsChan :: TQueue Event
, envWindow :: !GLFW.Window
, envGear1 :: !GL.DisplayList
, envGear2 :: !GL.DisplayList
, envGear3 :: !GL.DisplayList
, envPlane :: !GL.DisplayList
, envBlobs :: ![Blob]
, envZDistClosest :: !Double
, envZDistFarthest :: !Double
}
data State = State
{ stateWindowWidth :: !Int
, stateWindowHeight :: !Int
, stateXAngle :: !Double
, stateYAngle :: !Double
, stateZAngle :: !Double
, stateGearZAngle :: !Double
, stateZDist :: !Double
, stateMouseDown :: !Bool
, stateDragging :: !Bool
, stateDragStartX :: !Double
, stateDragStartY :: !Double
, stateDragStartXAngle :: !Double
, stateDragStartYAngle :: !Double
}
type Demo = RWST Env () State IO
And retrieving something from that environment is easy enough:
blobs <- asks envBlobs
But I also need to be able to modify the value of those "variables". Would I need to move that to the state, to be able to change it's value or can I also modify the contents of the "env" part of things?
But I also need to be able to modify the value of those "variables". Would I need to move that to the state, to be able to change it's value or can I also modify the contents of the "env" part of things?
It depends on whether you want to modify those env values "locally", in a computation under your control, or you want to modify them for any possible computation that might come afterwards.
In the first case, you can get by by using local:
local :: (r -> r) -> RWST r w s m a -> RWST r w s m a
When the RWST computation we pass to local exits, the values in the environment r will return to their original versions, unmodified by the r -> r function.
But if you want the changes to be "sticky", you'll need to move those values to the state and use functions like put or modify.
An example:
import Control.Monad.IO.Class
import Control.Monad.Trans.RWS.Strict
action :: RWST Int () Char IO ()
action = do
local succ $ do -- affects only the nested action
v <- ask
liftIO $ print v
do
v <- ask
liftIO $ print v -- isn't affected by local
modify succ -- change seen by the following actions
do
s <- get
liftIO $ print s -- is affected by modify
main :: IO ()
main = do
(_, _, _) <- runRWST action 0 'a'
return ()
-- Results:
-- 1
-- 0
-- 'b'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With