[Haskell-cafe] Fwd: Monad Transformers stack with variable depth

leonidasbo . leonidasbo at gmail.com
Tue Mar 6 22:46:44 UTC 2018


I am a beginner with Haskell and the last few days I am troubled on how to
form a stack of Monad Transformers.
The following example demonstrates the use of multiple State monads without
the use of Monad Transformers:

data Item = Item { rCounter :: Int }

increaseCounter :: State Item ()
increaseCounter = do
  val <- gets rCounter
  modify (\i -> i { rCounter = val + 1 })

data ItemManager = ItemManager { rItems :: [Item] }

addItem :: Item -> State ItemManager ()
addItem item = do
  items <- gets rItems
  modify (\mgr -> mgr { rItems = items ++ [item] })

increaseCounterInItems :: State ItemManager ()
increaseCounterInItems = do
  items <- gets rItems
  let items' = map *(execState increaseCounter)* items
  modify (\mgr -> mgr { rItems = items' })

main :: IO ()
main = $ do
  let itemMgrState = do
        addItem $ Item 0
        addItem $ Item 10

  let itemMgr = execState itemMgrState $ ItemManager []

  let items = rItems itemMgr
  putStrLn rCounter (items !! 0) -- prints 1
  putStrLn rCounter (items !! 1) -- prints 11

In the above implementation calls *execState, *inside functions of
ItemManager, for updating Items.
I have read about MonadTransformers and that they give you the ability to
use monads inside the context of another monad.
So I would like to use StateT in signatures of ItemManager's functions and
avoid calling *execState, *something like this:

increaseCounterInltems :: StateT ItemManager (State Item) ()

But I cannot find a way to implement the above function. The root cause of
the difficulty seems to be that ItemManager contains multiple Items.
The Monad Transformer stack contains a single State Item. So it seems to me
that I am following the wrong approach.

How could I use Monad Transformers in order to avoid calling *execState*
for modifying Items in ItemManager?

Thanks in advance,

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20180307/9bf65c8a/attachment.html>

More information about the Haskell-Cafe mailing list