Monad transformer stack confusion - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Sridhar Ratnakumar

Newbie question. I can't believe I'm still struggling to grapple MTL stuff. The lucid library has HtmlT m a which has a MonadState instance. But how exactly do you use it? I tried flip runState mempty someFunc where someFunc is MonadState String m => HtmlT m () but that doesn't compile.

Sridhar Ratnakumar

StateT String (HtmlT Identity) () seems one step forward, but then you have to lift all UI elements, thus losing access to state.

Sridhar Ratnakumar

Aha, flip runStateT mempty $ evalHtmlT someFunc works.

Sridhar Ratnakumar

Grr, but that doesn't render the Html at runtime

Sridhar Ratnakumar

Okay, after reading the source ... unpack and pack it back: HtmlT $ fmap fst $ flip runStateT mempty $ runHtmlT someFunc

Sandy Maguire

you're doing something cray here!

Sandy Maguire

monad transformers should only need to be unpeeled in main

Sandy Maguire

flip runState myState $ runHtmlT myHTMLFUNCTION

Sandy Maguire

the State here is global

Sandy Maguire

if you want local state semantic, you want to build a StateT s Html instead

Sridhar Ratnakumar

With StateT s Html you would have lift when rendering UI, but at that point - access to state is lost.

Sridhar Ratnakumar

And it seems that the lucid library recommends putting State inside the HtmlT transformer: https://hackage.haskell.org/package/lucid-2.9.12/docs/Lucid.html#t:HtmlT

Sridhar Ratnakumar

So to "inject" an inner monad, I had to peel the skin, apply the topical cream (runState), then put it back.

Sridhar Ratnakumar

(well, that reads pretty gory)