
On Tue, Dec 6, 2011 at 3:03 PM, Bas van Dijk
On 6 December 2011 12:59, Michael Snoyman
wrote: On Tue, Dec 6, 2011 at 11:49 AM, Bas van Dijk
wrote: On 6 December 2011 05:06, Michael Snoyman
wrote: Maybe this will help[1]. It's using RWST instead of StateT, but it's the same idea.
[1] https://github.com/yesodweb/yesod/commit/7619e4e9dd88c152d1e00b6fea073c3d52d...
Hi Michael,
Note that you can just reuse the MonadTransControl instance of the RWST transformer:
instance MonadTransControl (GGWidget master) where newtype StT (GGWidget master) a = StWidget {unStWidget :: StT (GWInner master) a} liftWith f = GWidget $ liftWith $ \run -> f $ liftM StWidget . run . unGWidget restoreT = GWidget . restoreT . liftM unStWidget
Cheers,
Bas
Thanks Bas, I was just in the process of converting Widget from being a RWS to a Writer, and your code made it much simpler :).
Michael
Do you think it's useful to have the following two utility functions for defining a MonadTransControl instance for your own monad transformer provided that your transformers is defined in terms of another transformer:
defaultLiftWith ∷ (Monad m, MonadTransControl tInner) ⇒ (tInner m α → t m α) -- ^ Constructor → (∀ β n. t n β → tInner n β) -- ^ Deconstructor → (∀ β. StT tInner β → StT t β) -- ^ State constructor → ((Run t → m α) → t m α) defaultLiftWith con deCon st = \f → con $ liftWith $ \run → f $ liftM st ∘ run ∘ deCon
defaultRestoreT ∷ (Monad m, MonadTransControl tInner) ⇒ (tInner m α → t m α) -- ^ Constructor → (StT t α → StT tInner α) -- ^ State deconstructor → (m (StT t α) → t m α) defaultRestoreT con unSt = con ∘ restoreT ∘ liftM unSt
For example in your case you would use these as follows:
instance MonadTransControl (GGWidget master) where newtype StT (GGWidget master) a = StWidget {unStWidget :: StT (GWInner master) a} liftWith = defaultLiftWith GWidget unGWidget StWidget restoreT = defaultRestoreT GWidget unStWidget
Bas
I don't have a strong opinion, but it sounds like a net win, assuming the documentation clearly explains how they are supposed to be used. Michael