2013-05-08 66 views
1

我想设定一个网页包含本年度标题为一个字符串,像这样:的setTitle与类型的错误IO字符串结果

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单子(或解除setTitle功能进去)。我尝试了各种各样的事情,但都没有成功,所以这可能归结为我还没有理解Haskell的类型系统;-)你能启发我吗?

+0

欢迎来到SO(尽管您已经是会员一段时间了)。我在你的问题中解决了一些问题。请花些时间阅读http://stackoverflow.com/faq了解网站的工作原理。 – pmr 2013-05-08 08:42:44

+0

谢谢!你刚刚从标题中删除了标签,因为它们是多余的,对吧? – 2013-05-08 13:53:57

+0

是的,没错。 – pmr 2013-05-08 14:17:27

回答

2

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

import Control.Monad.IO.Class (liftIO) 

getRootR = do 
    [...] 
    defaultLayout $ do 
     unwrappedTitle <- liftIO title 
     setTitle unwrappedTitle 
    [...] 
+0

很高兴你找到了丢失的链接:) – 2013-05-09 04:26:56

5

您的title不是Html价值本身。它被包裹在IO中。你必须先提取它。

getRootR = do 
    [...] 
    defaultLayout $ do 
     unwrappedTitle <- title 
     setTitle unwrappedTitle 
    [...] 
+0

非常感谢你的回答Mihai。我试过了,但后来我得到: 无法匹配预期的类型'GWidget sub0 a0 t0' 与实际类型'IO Html' 在“do”块的标题中:unwrappedTitle < - title – 2013-05-08 13:39:28

+0

对不起格式不正确,我与反引号战斗;-) – 2013-05-08 13:46:27

+0

'setTitle'的类型是什么? – 2013-05-08 14:23:46

相关问题