Search code examples
haskellhaskell-lens

When should I use MonadState lens combinators?


I understand that a MonadState s m gives me ability to get and update an s.

I do not however understand how this state is related to the state used in lens combinators like assign. Especially when lens can operate on multiple targets. Also, there are simpler functions like set that do not require state.

What are use cases for each of those similar combinators?


Solution

  • I recommend you to read this excellent blog post about using lens within MonadState. It gives you examples of how awesome Haskell could be.

    http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html

    Regarding your question about difference between assign and set: assign is just a version of set that operates inside MonadState. That's it. You can observe this fact through implementation.

    Let me give some examples.

    You can use set to just set (sorry for repetition) some field of some object:

    ghci> set _2 42 ([0.1, 0.2], 3)
    ([0.1,0.2],42)
    

    If you want to use assign you need to call this function inside some State context. For example consider next simple function:

    assignMe :: Int -> StateT ([Double], Int) IO ()
    assignMe x = do
        before <- get
        liftIO $ putStrLn $ "before assignment: " ++ show before
        assign _2 x
        after <- get
        liftIO $ putStrLn $ "after assignment: " ++ show after
    

    If you now call this function in ghci you can observe result of its execution:

    ghci> execStateT (assignMe 42) ([0.1,0.2], 3)
    before assignment: ([0.1,0.2],3)
    after assignment: ([0.1,0.2],42)
    ([0.1,0.2],42)
    

    That's it. assign just behaves like set except it applies lens to state.