
Dear Café, TL;DR: What is the canonical way to deal with state in Yesod? IORef? StateT? Routes? Subsites? The Yesod book [1,2] gives examples where state is encoded in an IORef inside the foundational type, like so: data AppState = ... data App = App {appState :: IORef AppState} All handlers would then first read the AppState via getsYesod appState >>= (liftIO . readIORef) and branch on the result. I wonder if there are other ways to deal with state that changes through user interaction. After all, we have instance MonadHandler m => MonadHandler (StateT s m) in Yesod.Core. What is this useful for? From [1]: "By just providing you with a readable environment, you’re able to recreate a StateT transformer by relying on mutable references." also: "In order to run these [monad transformer actions], we can use the standard [...] unwrap functions [...] to run the action and get back a normal Handler." I interpret quote 1 as "StateT is to be emulated (via IORef), not used literally" and quote 2 as "real StateT can not be used directly, but must be unwrapped to be used in a handler". Context for my question: I found that Kleisli maps model wizards nicely as a sequence of fragments, e.g. Program User f :: () -> m a g :: a -> m b h :: b -> m c i :: c -> m d j :: d -> m () wizard :: m () wizard = (f >=> g >=> h >=> i >=> j) () The intermediate types a, c are questions and b, d are answers, and all types together form the program states. If the user side of the wizard is to be provided by websites, we need to model these states explicitly somehow. My current approach is to use the union type AppState = Start | Answer1 b | Answer2 d that tells the handler what step to serve next. Olaf [1] https://www.yesodweb.com/book/yesods-monads#yesods-monads_adding_a_new_monad... [2] https://www.yesodweb.com/book/visitor-counter