4

我在我的第一个网站上使用 Yesod,我有一个新闻列表:

NewsItem
    date    UTCTime default=CURRENT_TIME
    title   String
    content String
    author  String

在我的处理程序中检索到:

newsitems <- runDB $ selectList [] [Desc NewsItemDate]

并最终在我的模板中使用:

$if null newsitems
    <p>No news.
$else
    $forall Entity id entry <- newsitems
        <article>
            <h4>#{newsItemDate entry}
            <p>#{newsItemContent entry}

但我收到有关数据类型的错误:

Handler/Home.hs:20:11:
    No instance for (Text.Blaze.ToMarkup
                       time-1.4:Data.Time.Clock.UTC.UTCTime)
      arising from a use of `toHtml'
    Possible fix:
      add an instance declaration for
      (Text.Blaze.ToMarkup time-1.4:Data.Time.Clock.UTC.UTCTime)
    In the first argument of `toWidget', namely
      `toHtml (newsItemDate entry_a6ev)'
    In a stmt of a 'do' block:
      toWidget (toHtml (newsItemDate entry_a6ev))
    In the expression:
      do { toWidget
             ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
                "<article><h4>");
           toWidget (toHtml (newsItemDate entry_a6ev));
           toWidget
             ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
                "</h4>\
                \<p>");
           toWidget (toHtml (newsItemContent entry_a6ev));
           .... }

所以我想我会继续添加到我的 Import.hs 中:

import Data.Time (UTCTime)
import Data.Time.Format (formatTime)
import Text.Blaze (ToMarkup, toMarkup)
import Text.Blaze.Internal (string)
import System.Locale (defaultTimeLocale)

-- format date as     26 July 2012
instance ToMarkup UTCTime where
   toMarkup a = string (formatTime defaultTimeLocale "%e %B %Y" a)

哪个可以编译,但在浏览器运行时给我一个错误:

Internal Server Error
PersistMarshalError "Expected UTCTime, received PersistText \"2012-08-30\""

所以我不确定如何解决这个问题,有什么想法吗?

编辑:网站的源代码,以防需要或好奇:https ://github.com/iaefai/socrsite

4

2 回答 2

4

在不调查实际错误的情况下,我认为您的方法不是很好。你很可能最终会想要几种格式化 a 的方法UTCTime,毕竟类型是用来存储时间的,而不仅仅是日期。通过提供一个ToMarkup UTCTime实例,您可以全局解决此问题。

我建议编写函数renderAsDate :: UTCDate -> HTMLrenderAsTime :: UTCDate -> HTML并在您的模板中使用它们,例如#{renderAsDate (newsItemDate entry)}.

但这不会解决运行时错误,它来自序列化层并且可能与您的模板无关。

于 2012-09-05T07:18:55.777 回答
1

我很确定你可以在小村庄里使用表演吗?这至少是我所做的......

#{show $ newsItemDate entry}

我以前遇到过这个实例,正如这个人在这里描述的那样:

作为这种节俭表达哲学的一部分,Haskell 不需要类型签名——尽管有经验的 Haskeller 提供它们是为了清楚起见——所以这种强类型语言中的类型错误对于外行来说通常是神秘的。例如,如果你定义一个函数 f 将两个数字相加,然后用两个字符串调用它,编译器不会抱怨错误的参数,它会抱怨字符串不支持 operator plus。它会以一种非常不明显的方式来表达这种抱怨。[1] 在“1. Haskell 很简洁”下...

[1] http://fpcomplete.com/ten-things-you-should-know-about-haskell-syntax/

于 2012-11-15T22:08:59.107 回答