YesodAuthEmail could not deduce m ~ HandlerFor sit

2019-02-19 11:32发布

This question already has an answer here:

I'm trying to add

instance YesodAuthEmail App 

to the Yesod-Postgres scaffolding (yesod version 1.6) and getting stuck on a compile error.

The relevant code is:

instance YesodAuth App where
     type AuthId App = UserId
     ....
     authPlugins :: App -> [AuthPlugin App]
     authPlugins app = [authOpenId Claimed []] ++ extraAuthPlugins
         where extraAuthPlugins = [ authEmail ]

instance YesodAuthEmail App where
    type AuthEmailId App = UserId

    afterPasswordRoute _ = HomeR

    addUnverified email verkey =
        runDB $ insert $ User email Nothing 

The error I receive is:

/home/justin/code/yesodemail/src/Foundation.hs:273:11: error:
• Could not deduce: m ~ HandlerFor site0 from the context: MonadAuthHandler App m bound by the type signature for: addUnverified :: Yesod.Auth.Email.Email -> VerKey -> AuthHandler App (AuthEmailId App) ....
Expected type: m (AuthEmailId App) Actual type: HandlerFor site0 (Key User)

Based on the types,

getEmail :: AuthEmailId site -> AuthHandler site (Maybe Email) 
type MonadAuthHandler master m = (MonadHandler m, YesodAuth master, master ~ HandlerSite m, Auth ~ SubHandlerSite m, MonadUnliftIO m)
type AuthHandler master a = forall m. MonadAuthHandler master m => m a

I would have thought this would compile. What I am misunderstanding?

P.S. I've tried to include everything relevant, but the full Foundation.hs is at https://gist.github.com/hyperpape/39d4d2baf67d3bdbdba45a943e7e0425

1条回答
Fickle 薄情
2楼-- · 2019-02-19 12:07

The type of runDB is:

runDB :: YesodDB site a -> HandlerFor site a 

in order to call it in AuthHandler you need to lift it to HandlerFor.

If I am not mistaken this is what the liftHandler method from MonadHandler is for.

If you compose your runDB call with it, it should work:

addUnverified email verkey =
    liftHandler . runDB $ insert $ User email Nothing

I found a detailed answer to your question here.

查看更多
登录 后发表回答