質問

I am building a survey site in Yesod (0.10) and am getting lost in the types. Here is a simplified version on what I am trying to do.

invitation url = do
   render <- getUrlRender
   return $ renderHtml [hamlet|
<p>Dear foo, please take our 
   <a href=@{ShowSurveyR url}>survey.
|] render

Another function is going to call this in hopes of getting something that can be passed to simpleMail from Network.Mail.Mime. The above function gives a type error:

Handler/Root.hs:404:13:
    The function `renderHtml' is applied to two arguments,
    but its type `Html -> LT.Text' has only one

This is confusing, because the templates tutorial seems to do things this way. But if I modify the code, like this...

invitation url = do
   return $ renderHtml [hamlet|
<p>Dear foo, please take our
   <a href=@{ShowSurveyR url}>survey.
|]

I get this type error.

Handler/Root.hs:403:24:
    The lambda expression `\ _render[a4TO] -> ...' has one argument,
    but its type `Html' has none
    In the first argument of `renderHtml', namely

I think that renderHtml is the wrong function to use, but I can't find what the right function is. Does anyone know what I am missing? How am I supposed to pass the routing function into my hamlet code?

役に立ちましたか?

解決

The quasiquote ([hamlet|...|]) returns a function whose argument is also a function. You must first apply that quasiquote value, and pass the results to renderHtml:

[Edit: as @MattoxBeckman discovered, another issue is the need to use getUrlRenderParams instead of gutUrlRender.]

invitation url = do
  render <- getUrlRenderParams
  return $ renderHtml $ [hamlet|
<p>Dear foo, please take our 
<a href=@{ShowSurveyR url}>survey.
|] render

(Note the additional $).

P.S. renderHtml is of type Html -> Text, while the result of the quasiquote, [hamlet|..|], is of type Render url -> Html. The first error message you saw notes that you tried to pass two arguments to renderHtml, while the second error message notes that you didn't pass any arguments to the quasiquote value.

他のヒント

To make this easier for the next person who goes searching for it...

There were two problems. One was pointed out by the first answer; the hamlet quasiquoter itself takes a function. The other problem was that I needed to use the function getUrlRenderParams, not getUrlRender. The final code is

invitation :: Text -> Handler LT.Text
invitation url = do
   render <- getUrlRenderParams
   return $ renderHtml $ [hamlet|
<p>Dear foo, please take our
   <a href=@{ShowSurveyR url}>survey.
|] render

Just replace shamlet instead of hamlet; it doesn't need a render argument at all.

(As was pointed to me by joelteon at #yesod.)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top