On Tue, Dec 6, 2011 at 3:03 PM, Bas van Dijk <v.dijk....@gmail.com> wrote: > On 6 December 2011 12:59, Michael Snoyman <mich...@snoyman.com> wrote: >> On Tue, Dec 6, 2011 at 11:49 AM, Bas van Dijk <v.dijk....@gmail.com> wrote: >>> On 6 December 2011 05:06, Michael Snoyman <mich...@snoyman.com> 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/7619e4e9dd88c152d1e00b6fea073c3d52dc797f#L0R105 >>> >>> 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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe