我试图为Yesod的电子邮件身份验证插件编写apLogin,并且表单助手正在抛出类型错误。 runFormPost无法读取loginForm。我尝试过几种不同的类型签名组合,但这个错误信息似乎最清楚。好像我有错误的顶级约束,或者我错过了一个。设置它的最佳方法是什么,以便推断出正确的类型?
authEmail :: (YesodAuthEmail m) => AuthPlugin m
authEmail =
AuthPlugin "email" dispatch login
where
login toParent =
toWidget $ do
((_,widget),enctype) <- runFormPost loginForm
[whamlet|
<form method="post" action="@{toParent loginR}">
|]
loginForm extra = do
let emailSettings = FieldSettings {
fsLabel = SomeMessage Msg.Email,
fsTooltip = Nothing,
fsId = Just "email",
fsName = Just "email",
fsAttrs = [("autofocus", "")]
}
(emailRes, emailView) <- mreq emailField emailSettings Nothing
let userRes = UserForm <$> emailRes
let widget = do
[whamlet|
#{extra}
^{fvInput emailView}
|]
return (userRes, widget)
这是错误:
Could not deduce (MonadIO m0) arising from a use of ‘loginForm’
from the context (YesodAuthEmail m)
bound by the type signature for
authEmail :: YesodAuthEmail m => AuthPlugin m
at Yesod/Auth/Email.hs:260:14-47
or from (MonadWidget m1, YesodAuth (HandlerSite m1))
bound by the inferred type of
login :: (MonadWidget m1, YesodAuth (HandlerSite m1)) =>
(AuthRoute -> Route (HandlerSite m1)) -> m1 ()
at Yesod/Auth/Email.hs:(270,5)-(275,14)
The type variable ‘m0’ is ambiguous
Note: there are several potential instances:
instance MonadIO m =>
MonadIO
(conduit-1.2.6.1:Data.Conduit.Internal.Conduit.ConduitM i o m)
-- Defined in ‘conduit-1.2.6.1:Data.Conduit.Internal.Conduit’
instance MonadIO m =>
MonadIO (conduit-1.2.6.1:Data.Conduit.Internal.Pipe.Pipe l i o u m)
-- Defined in ‘conduit-1.2.6.1:Data.Conduit.Internal.Pipe’
instance MonadIO IO -- Defined in ‘Control.Monad.IO.Class’
...plus 18 others
In the first argument of ‘runFormPost’, namely ‘loginForm’
In a stmt of a 'do' block:
((_, widget), enctype) <- runFormPost loginForm
In the second argument of ‘($)’, namely
‘do { ((_, widget), enctype) <- runFormPost loginForm;
(do { (asWidgetT . toWidget)
((Text.Blaze.Internal.preEscapedText . T.pack)
"<form method=\"post\" action=\"");
(getUrlRenderParams
>>=
(\ urender_ajDM
-> (asWidgetT . toWidget)
(toHtml (\ u_ajDN -> urender_ajDM u_ajDN ... (toParent loginR)))));
(asWidgetT . toWidget)
((Text.Blaze.Internal.preEscapedText . T.pack)
"\"></form>\n") }) }’
使用handlerToWidget更正的代码:
authEmail :: (YesodAuthEmail m) => AuthPlugin m
authEmail =
AuthPlugin "email" dispatch login
where
login toParent = do
((_,widget),enctype) <- handlerToWidget $ runFormPost loginForm
[whamlet|
<form method="post" action="@{toParent loginR}">
|]
loginForm extra = do
let emailSettings = FieldSettings {
fsLabel = SomeMessage Msg.Email,
fsTooltip = Nothing,
fsId = Just "email",
fsName = Just "email",
fsAttrs = [("autofocus", "")]
}
(emailRes, emailView) <- mreq emailField emailSettings Nothing
let userRes = UserForm <$> emailRes
let widget = do
[whamlet|
#{extra}
^{fvInput emailView}
|]
return (userRes, widget)
错误:
Could not deduce (MonadIO m0) arising from a use of ‘loginForm’
from the context (YesodAuthEmail m)
bound by the type signature for
authEmail :: YesodAuthEmail m => AuthPlugin m
at Yesod/Auth/Email.hs:260:14-47
or from (MonadIO m1,
MonadBaseControl IO m1,
exceptions-0.8.2.1:Control.Monad.Catch.MonadThrow m1,
YesodAuth site)
bound by the inferred type of
login :: (MonadIO m1, MonadBaseControl IO m1,
exceptions-0.8.2.1:Control.Monad.Catch.MonadThrow m1,
YesodAuth site) =>
(AuthRoute -> Route site) -> WidgetT site m1 ()
at Yesod/Auth/Email.hs:(270,5)-(275,14)
The type variable ‘m0’ is ambiguous
Note: there are several potential instances:
instance MonadIO m =>
MonadIO
(conduit-1.2.6.1:Data.Conduit.Internal.Conduit.ConduitM i o m)
-- Defined in ‘conduit-1.2.6.1:Data.Conduit.Internal.Conduit’
instance MonadIO m =>
MonadIO (conduit-1.2.6.1:Data.Conduit.Internal.Pipe.Pipe l i o u m)
-- Defined in ‘conduit-1.2.6.1:Data.Conduit.Internal.Pipe’
instance MonadIO IO -- Defined in ‘Control.Monad.IO.Class’
...plus 18 others
In the first argument of ‘runFormPost’, namely ‘loginForm’
In the second argument of ‘($)’, namely ‘runFormPost loginForm’
In a stmt of a 'do' block:
((_, widget), enctype) <- handlerToWidget $ runFormPost loginForm
没有toWidgetHandler错误:
Could not deduce (MonadIO m0) arising from a use of ‘loginForm’
from the context (YesodAuthEmail m)
bound by the type signature for
authEmail :: YesodAuthEmail m => AuthPlugin m
at Yesod/Auth/Email.hs:260:14-47
or from (MonadIO m1,
MonadBaseControl IO m1,
exceptions-0.8.2.1:Control.Monad.Catch.MonadThrow m1,
YesodAuth site)
bound by the inferred type of
login :: (MonadIO m1, MonadBaseControl IO m1,
exceptions-0.8.2.1:Control.Monad.Catch.MonadThrow m1,
YesodAuth site) =>
(AuthRoute -> Route site) -> WidgetT site m1 ()
at Yesod/Auth/Email.hs:(271,5)-(275,10)
The type variable ‘m0’ is ambiguous
Note: there are several potential instances:
instance MonadIO m =>
MonadIO
(conduit-1.2.6.1:Data.Conduit.Internal.Conduit.ConduitM i o m)
-- Defined in ‘conduit-1.2.6.1:Data.Conduit.Internal.Conduit’
instance MonadIO m =>
MonadIO (conduit-1.2.6.1:Data.Conduit.Internal.Pipe.Pipe l i o u m)
-- Defined in ‘conduit-1.2.6.1:Data.Conduit.Internal.Pipe’
instance MonadIO IO -- Defined in ‘Control.Monad.IO.Class’
...plus 18 others
In the first argument of ‘runFormPost’, namely ‘loginForm’
In a stmt of a 'do' block:
((_, widget), enctype) <- runFormPost loginForm
In the expression:
do { ((_, widget), enctype) <- runFormPost loginForm;
(do { (asWidgetT . toWidget)
((Text.Blaze.Internal.preEscapedText . T.pack)
"<form method=\"post\" action=\"");
(getUrlRenderParams
>>=
(\ urender_ajDM
-> (asWidgetT . toWidget)
(toHtml (\ u_ajDN -> urender_ajDM u_ajDN ... (toParent loginR)))));
(asWidgetT . toWidget)
((Text.Blaze.Internal.preEscapedText . T.pack) "\"></form>\n") }) }
答案 0 :(得分:0)
我不确定,但我认为您的toWidget
电话是您的主要问题。此外,您还需要将runFormPost
从处理程序升级到窗口小部件,这可以通过handlerToWidget
完成。