我正在尝试将网页标题设置为包含当前年份的字符串,如下所示:
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的类型系统;-)你能启发我吗?
答案 0 :(得分:5)
您的title
本身不是Html
值。它包含在IO
中。你必须先提取它。
getRootR = do
[...]
defaultLayout $ do
unwrappedTitle <- title
setTitle unwrappedTitle
[...]
答案 1 :(得分:2)
耶,发现它!解决方案是使用liftIO
:
import Control.Monad.IO.Class (liftIO)
getRootR = do
[...]
defaultLayout $ do
unwrappedTitle <- liftIO title
setTitle unwrappedTitle
[...]