我有一个脚手架的Yesod应用程序并创建了一个看起来像这样的简单小部件,它位于单独的模块中:
module Widget.Header where
import Prelude
import Yesod
twitterWidget :: MonadWidget m => String -> m ()
twitterWidget twitteruser = do
toWidgetBody([hamlet| <a href="https://twitter.com/#{twitteruser}" .twitter-follow-button data-show-count="false">Follow @#{twitteruser}
<script async src="//platform.twitter.com/widgets.js" charset="utf-8">
|])
我已将此模块包含在.cabal文件中,我可以在Handler中加载它并且一切正常。
twitterUsername :: String
twitterUsername = "someusername"
getHomeR :: Handler Html
getHomeR = do
(formWidget, formEnctype) <- generateFormPost sampleForm
let submission = Nothing :: Maybe FileForm
handlerName = "getHomeR" :: Text
defaultLayout $ do
let (commentFormId, commentTextareaId, commentListId) = commentIds
aDomId <- newIdent
setTitle "Some title"
twitterWidget twitterUsername
$(widgetFile "homepage")
所以我想做的是直接在另一个模板中使用它,但是当我尝试这样做时:
^{twitterWidget twitterUsername}
我得到了
• Ambiguous type variable ‘m1’ arising from a use of ‘toWidget’
prevents the constraint ‘(ToWidget App (m1 ()))’ from being solved.
Probable fix: use a type annotation to specify what ‘m1’ should be.
These potential instances exist:
instance (site' ~ site, IO ~ m, a ~ ()) =>
ToWidget site' (WidgetT site m a)
-- Defined in ‘Yesod.Core.Widget’
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the second argument of ‘(GHC.Base..)’, namely ‘toWidget’
In the expression: asWidgetT GHC.Base.. toWidget
In a stmt of a 'do' block:
(asWidgetT GHC.Base.. toWidget) (twitterWidget twitterUsername)
所以我的问题是,在网站周围的模板中加载多个小部件以实现不同目的的正确方法是什么?
答案 0 :(得分:1)
改变你的
module Widget.Header where
import Prelude
import Yesod
twitterWidget :: MonadWidget m => String -> m ()
twitterWidget twitteruser = do
toWidgetBody([hamlet| <a href="https://twitter.com/#{twitteruser}" .twitter-follow-button data-show-count="false">Follow @#{twitteruser}
<script async src="//platform.twitter.com/widgets.js" charset="utf-8">
|])
更像是
module Widget.Header where
import Import
twitterWidget :: Yesod site => String -> WidgetT site IO ()
twitterWidget twitteruser = do
toWidgetBody([hamlet| <a href="https://twitter.com/#{twitteruser}" .twitter-follow-button data-show-count="false">Follow @#{twitteruser}
<script async src="//platform.twitter.com/widgets.js" charset="utf-8">
|])
那样m
肯定会成为IO
,而Haskell则无需弄明白。