1

我正在尝试将网页的标题设置为包含当前年份的字符串,如下所示:

getCurrentYear :: IO String
getCurrentYear = do
    now <- getCurrentTime
    let today = utctDay now
    let (year, _, _) = toGregorian today
    return $ show year

title :: IO Html
title = do
    y <- getCurrentYear
    return $ toHtml $ "Registration " ++ y

getRootR :: Handler RepHtml
getRootR = do
    (widget, enctype) <- generateFormPost personForm -- not important for the problem at hand, comes from the example in the yesod book
    defaultLayout $ do
        setTitle title -- this is where I get the type error
[...]

当我尝试编译它时,我在该setTitle行收到以下错误:

Couldn't match expected type `Html' with actual type `IO Html'
In the first argument of `setTitle', namely `title'
[...]

我只是无法从 IO monad 中获取当前年份(或将setTitle函数提升到其中)。我已经尝试过各种事情但没有成功,所以这可能归结为我仍然不了解 Haskell 的类型系统 ;-) 你能启发我吗?

4

2 回答 2

5

title本身不是一个Html价值。它被包裹在IO. 你必须先提取它。

getRootR = do
    [...]
    defaultLayout $ do
        unwrappedTitle <- title
        setTitle unwrappedTitle
    [...]
于 2013-05-08T08:38:13.727 回答
2

耶,找到了!!!解决方案是使用liftIO

import Control.Monad.IO.Class (liftIO)

getRootR = do
    [...]
    defaultLayout $ do
        unwrappedTitle <- liftIO title
        setTitle unwrappedTitle
    [...]
于 2013-05-08T22:05:17.217 回答