[web-devel] [Yesod] teach me how to convert 0.6.7 to 0.7.1

Michael Snoyman michael at snoyman.com
Mon Feb 21 07:05:58 CET 2011

A simple workaround that *should* work:

 xs <- runDB $ selectList [UserNameEq x] [] 0 0
 defaultLayout $ do
     setTitle $ string $ "homepage"
     addHamlet $(hamletFile "homepage")

The rest of this email is a little technical: One of the changes in
WAI 0.3 is that the application itself runs in the Iteratee monad
instead of the IO monad. This works fine for the most part, since
Iteratee is an instance of MonadIO. However, Iteratee is *not* an
instance of MonadPeelIO. Persistent, on the other hand, *must* run in
a MonadPeelIO since it uses MonadPeelIO's error handling code to
ensure resource cleanup.

Therefore, in Yesod 0.7, GHandler and GWidget were given more generic
siblings, GGHandler and GGWidget (I'm so creative with naming, I
know). These allow any arbitrary inner monad, including Iteratee and
IO. When running Persistent code through runDB, the inner monad is IO,
and the runDB lifts the inner IO into an Iteratee. Overall, this works
without a hitch.

The only downside is that you cannot call functions that require an
Iteratee inner monad from inside Persistent calls anymore. The
practical ramification is that you cannot parse POST parameters inside
of Persistent (the Iteratee is how WAI passes in the request body).
defaultLayout itself could in theory want to parse those parameters,
and therefore its type signature is GGHandler Iteratee. Therefore, it
cannot be lifted into a Persistent call.

The workaround I gave simply returns the data from Persistent to
outside of the runDB call. There shouldn't be any performance impact,
it's merely a style change.

Hope that was clear,

On Mon, Feb 21, 2011 at 2:29 AM, Katsutoshi Itoh <cutsea110 at gmail.com> wrote:
> Hi,
> i'm trying to convert my apps from yesod-0.6.7 to yesod-0.7.1.
> If you do the following: How would I change?
> on yesod-0.6.7.
> RootR = do
>   :
>   :
>  runDB $ do
>    xs <- selectList [UserNameEq x] [] 0 0
>    lift $ defaultLayout $ do
>      setTitle $ string $ "homepage"
>      addHamlet $(hamletFile "homepage")
> on yesod-0.7.1, an error occurred like as:
> Couldn't match expected type `YesodDB
>                                                             MyApp
> (GGHandler MyApp MyApp IO) RepHtml
>              against inferred type `t (GGHandler
>                                                             sub
>                                                             master
> (Data.Enumerator.Iteratee
> Data.ByteString.Internal.ByteString IO)) RepHtml'
>     NB: `YesodDB' is a type function, and may nnot be injective
>  In the expression:
>           lift
>      $     defaultLayout
>           $ do {  setTitle
>                     $ ......
> I guess convert `lift' to somewhat...
> would you teach me how to convert this?
> _______________________________________________
> web-devel mailing list
> web-devel at haskell.org
> http://www.haskell.org/mailman/listinfo/web-devel

More information about the web-devel mailing list