I've just migrated from current yesod scaffold to latest yesod-1.6.0
, yesod-auth-1.6.2
.
instance YesodAuth App where
type AuthId App = UserId
-- ....
authenticate creds = runDB $ do
x <- getBy $ UniqueUser $ credsIdent creds
case x of
Just (Entity uid _) -> return $ Authenticated uid
Nothing -> return $ UserError InvalidUsernamePass
Before migration this code worked well. But after the following error occurs.
.../src/Foundation.hs:212:26: error:
• Could not deduce: m ~ HandlerFor site8
from the context: (MonadHandler m, HandlerSite m ~ App)
bound by the type signature for:
authenticate :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ App) =>
Creds App -> m (AuthenticationResult App)
at src/Foundation.hs:212:5-16
‘m’ is a rigid type variable bound by
the type signature for:
authenticate :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ App) =>
Creds App -> m (AuthenticationResult App)
at src/Foundation.hs:212:5-16
Expected type: m (AuthenticationResult App)
Actual type: HandlerFor site8 (AuthenticationResult App)
• In the expression:
runDB
$ do x <- getBy $ UniqueUser $ credsIdent creds
case x of
Just (Entity uid _) -> return $ Authenticated uid
Nothing -> return $ UserError InvalidUsernamePass
In an equation for ‘authenticate’:
authenticate creds
= runDB
$ do x <- getBy $ UniqueUser $ credsIdent creds
case x of
Just (Entity uid _) -> return $ Authenticated uid
Nothing -> return $ UserError InvalidUsernamePass
In the instance declaration for ‘YesodAuth App’
• Relevant bindings include
authenticate :: Creds App -> m (AuthenticationResult App)
(bound at src/Foundation.hs:212:5)
|
212 | authenticate creds = runDB $ do
| ^^^^^^^^^^...
I don't know why it can't pass type check. runDB
works well in places not related to yesod-auth
.
EDIT: I extracted codes that seems relevant.
class (MonadResource m, MonadLogger m) => MonadHandler m where
type HandlerSite m
type SubHandlerSite m
liftHandler :: HandlerFor (HandlerSite m) a -> m a
liftSubHandler :: SubHandlerFor (SubHandlerSite m) (HandlerSite m) a -> m a
instance MonadHandler (HandlerFor site) where
type HandlerSite (HandlerFor site) = site
type SubHandlerSite (HandlerFor site) = site
liftHandler = id
{-# INLINE liftHandler #-}
liftSubHandler (SubHandlerFor f) = HandlerFor f
{-# INLINE liftSubHandler #-}
newtype HandlerFor site a = HandlerFor
{ unHandlerFor :: HandlerData site site -> IO a
}
deriving Functor
instance MonadHandler (HandlerFor site) where
type HandlerSite (HandlerFor site) = site
type SubHandlerSite (HandlerFor site) = site
liftHandler = id
{-# INLINE liftHandler #-}
liftSubHandler (SubHandlerFor f) = HandlerFor f
{-# INLINE liftSubHandler #-}
With above definitions, I wonder the reason that the following cannot pass type check.
problem :: (MonadHandler m, HandlerSite m ~ App) => m ()
problem = (undefined :: HandlerFor App ())
• Could not deduce: m ~ HandlerFor App
from the context: (MonadHandler m, HandlerSite m ~ App)
bound by the type signature for:
problem :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ App) =>
m ()
at /intero/intero1940cny-TEMP.hs:210:1-52
‘m’ is a rigid type variable bound by
the type signature for:
problem :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ App) =>
m ()
at /intero/intero1940cny-TEMP.hs:210:1-52
Expected type: m ()
Actual type: HandlerFor App ()
• In the expression: (undefined :: HandlerFor App ())
In an equation for ‘problem’: problem = (undefined :: HandlerFor App ())
• Relevant bindings include
problem :: m ()
(bound at /intero/intero1940cny-TEMP.hs:211:1)