help with reader monad

后端 未结 3 446
暗喜
暗喜 2021-01-04 04:29

I am new at haskell, I have to write a program context-aware,so I thought I can use the Reader Monad for keeping the context read from a file, I know how to read the file p

3条回答
  •  执笔经年
    2021-01-04 05:08

    I think it's easiest if you look at how you would solve this problem without using Reader, then compare the translated version. Here's a trimmed-down example from a program I'm working on where the environment is a set of callback functions to update the display. It's slightly more complicated because it uses ReaderT instead of Reader, but everything works in basically the same way.

    runProcess :: Env -> State -> Action -> IO State
    runProcess env state action = do
      newstate <- processAction state action
      let ufunc = mainUFunc env              -- get the callback to update the display
      ufunc newstate                         -- update the display
      return newstate
    

    Now I'll change it to use the Reader monad to pass along the environment. Since the code was already in IO, it's necessary to use the monad transformer version, ReaderT.

    runProcessR :: State -> Action -> ReaderT Env IO State
    runProcessR state action = do
      newstate <- lift $ processAction state action
      env <- ask                              -- get the environment from the reader
      liftIO $ (mainUFunc env) newstate       -- updating is in IO; it needs to be lifted
      return newstate
    

    At this point, the program's main loop will essentially be:

    loop :: State -> ReaderT Env IO ()
    loop = do
      action <- liftIO getAction
      if action == EndLoop
        then return ()
        else do
          st' <- processActionR st action
          loop st'
    
    mainLoop :: IO ()
    mainLoop = do
      env <- setUpCallbacks
      let st = initState
      runReaderT $ loop st
    

    So that's how you can use Reader. Every function that used to take an environment parameter no longer needs to. Functions that don't take the environment can be used directly or lifted if they're monadic.

提交回复
热议问题