[Haskell-cafe] writing wizards in Yesod

Olaf Klinke olf at aatal-apotheke.de
Wed Aug 26 20:24:11 UTC 2020


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_transformer
[2] https://www.yesodweb.com/book/visitor-counter



More information about the Haskell-Cafe mailing list