【问题标题】:How to modify RWST environment variables in Haskell?如何在 Haskell 中修改 RWST 环境变量?
【发布时间】:2020-12-04 06:03:02
【问题描述】:

我正在尝试在一个名为“GLFW-b-Demo”的现有项目上构建自己的项目。

它显然是使用一种叫做“RWST”的东西来模拟环境和状态:

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

从那个环境中检索一些东西很容易:

blobs <- asks envBlobs

但我还需要能够修改那些“变量”的值。 我是否需要将其移至状态,以便能够更改它的值,或者我还可以修改“env”部分的内容吗?

【问题讨论】:

  • 大致来说,RWST r w s t 用于r 是只读的,w 是只写的(只追加),s 是读/写的。如果您需要从那时起修改某些值,通常必须使其成为读/写s 的一部分。

标签: haskell monads


【解决方案1】:

但我还需要能够修改那些“变量”的值。我是否需要将其移至状态,以便能够更改它的值,或者我还可以修改“env”部分的内容吗?

这取决于您是要在“本地”、在您控制的计算中修改这些 env 值,还是要为之后可能发生的任何可能的计算修改它们。

第一种情况,你可以使用local:

local :: (r -> r) -> RWST r w s m a -> RWST r w s m a

当我们传递给local 的RWST 计算退出时,r 环境中的值将返回到它们的原始版本,不会被r -&gt; r 函数修改。

但如果您希望更改具有“粘性”,则需要将这些值移动到状态并使用 put 或 modify 等函数。

一个例子:

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'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2020-09-10
    • 1970-01-01
    • 2017-07-16
    • 2016-01-06
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多