在 Haskell 和 Yesod 中显示 Handler monad 的价值的问题

Problem to show value out of Handler monad in Haskell and Yesod

我是 Haskell 的初学者,我还在学习,我在与 monad 相关的问题上停了下来。
问题是我想在模板中显示评论作者。
我不能那样做,因为当我从数据库中添加评论时,它总是在 Handler monad 中。
也许我的整个想法是错误的我不知道。

这是评论实体:

ManComment
text Text sqltype=varchar(500)
created UTCTime sqltype=DateTime
writer UserId Maybe sqltype=varchar(255) default=NULL  -- comment writer
manId ManifestationId sqltype=varchar(255) default=NULL
deriving Show Typeable

这是处理函数:

getManDetailsR :: ManifestationId -> Handler Html
getManDetailsR mid = do 
  (ui, user) <- requireAuthPair
  comments <- runDB $ getComFromMan mid
  defaultLayout $ do
     setTitle "Manifestation details"
     $(widgetFile "man-details")

小村庄文件的一部分(最后一行试图显示作者):

$if null comments 
  <h4>There is not comments! 
$else 
  $forall Entity cid com <- comments 
    <form method=post action=@{DeleteManCommentR mid cid}> 
      <li .list-group-item> 
        <div class="row"> 
         <div class="col-xs-10 col-md-11"> 
         <div> 
          <div .mic-info> By: <a href=@{ProfileR}>#{getCommentWriter $ com}</a> 

我想在这里找到一位评论作者:

getCommentWriter :: ManComment -> Handler Text
getCommentWriter c = do 
  user <- runDB $ get404 $ fromJust $ manCommentWriter c  --get writer from database
  let username = userIdent user 
  return username  -- but return puts in Handler monad

最终出现错误:

No instance for (blaze-markup-0.8.2.7:Text.Blaze.ToMarkup
                         (Handler Text))
        arising from a use of ‘toHtml’ 

您应该能够像在那里使用 comments 一样使用它:将它绑定到本地值并在您的 hamlet-file/code.

中访问它

当然你想把它与评论本身结合起来,所以我建议这样:


getCommentAndWriter :: ManComment -> Handler (Entity ManComment, Text)
getCommentAndWriter c = do 
  user <- runDB $ get404 $ fromJust $ manCommentWriter c  --get writer from database
  let username = userIdent user 
  return (c, username)

getManDetailsR :: ManifestationId -> Handler Html
getManDetailsR mid = do 
  (ui, user) <- requireAuthPair

  cs <- runDB $ getComFromMan mid
  comments <- forM cs getCommentAndWriter
  
  defaultLayout $ do
     setTitle "Manifestation details"
     $(widgetFile "man-details")
$if null comments 
  <h4>There is not comments! 
$else 
  $forall (Entity cid com, writer) <- comments 
    <form method=post action=@{DeleteManCommentR mid cid}> 
      <li .list-group-item> 
        <div class="row"> 
         <div class="col-xs-10 col-md-11"> 
         <div> 
          <div .mic-info> By: <a href=@{ProfileR}>#{writer}</a>

当然,如果可以的话,您应该同时查询这两个问题,但基本上这应该可行。


PS:如果你想使用更多的字段,你可能会想要使用一条记录——为了简单起见,我在这里选择将它组合起来。