AuthHandler函数和Handler函数的可组合性

时间:2018-11-03 15:48:10

标签: haskell yesod

此帖子的第一个标题是:升级到Yesod-auth-1.6:无法将类型“ Auth”与“ App”匹配-类型相等SubHandlerSite m ~ Auth

在升级到Yesod-1.6时,我正在为新类型而苦苦挣扎。

instance YesodAuth App where
    type AuthId App = UserFId
-- etc.

instance YesodAuthEmail App where
  type AuthEmailId App = UserFId
-- etc.

getSessionUser :: HandlerFor App User
getSessionUser = do
  mu <- maybeAuthId -- UserFId is both an instance of 'AuthId App' and 'AuthEmailId App'
  case mu of
    Nothing -> redirect HomeR
    Just u  -> fromString . T.unpack . fromJust <$> getEmail u

和编译错误:

• Couldn't match type ‘Auth’ with ‘App’
    arising from a use of ‘getEmail’
• In the second argument of ‘(<$>)’, namely ‘(getEmail u)’
  In the expression: fromString . unpack . fromJust <$> getEmail u
  In a case alternative:
      Just u -> fromString . unpack . fromJust <$> getEmail u

实际上,getEmail的类型签名为:

getEmail :: (YesodAuthEmail (HandlerSite m), MonadHandler m,
      MonadUnliftIO m, SubHandlerSite m ~ Auth) =>
     AuthEmailId (HandlerSite m) -> m (Maybe Email)


(ghci)> :t fromJust <$> maybeAuthId >>= getEmail
fromJust <$> maybeAuthId >>= getEmail
  :: (YesodAuthEmail (HandlerSite m), MonadHandler m,
      MonadUnliftIO m,
      AuthId (HandlerSite m) ~ AuthEmailId (HandlerSite m),
      SubHandlerSite m ~ Auth) =>
     m (Maybe Email)

我假设我需要解决类型相等约束SubHandlerSite m ~ Auth,但是我不知道该怎么做。

编辑: 好的,我退后一步,然后深入研究yesod的文档,以寻找解决我的问题的可能方法。我找不到合适的解决方案。也许我正在尝试解决错误的问题?

实际上,我的函数getSessionUserHandler a。 我想在getEmail中致电getSessionUsergetEmailAuthHandler的功能。

此外,ghci推断出的类型签名使我感到困惑: getEmail :: (YesodAuthEmail (HandlerSite m), MonadHandler m, MonadUnliftIO m, SubHandlerSite m ~ Auth) => AuthEmailId (HandlerSite m) -> m (Maybe Email) 而文档提供了这种类型签名: getEmail :: AuthEmailId site -> AuthHandler site (Maybe Email)

我的理解(请告诉我我是否错)是无法组合AuthHandler函数和Handler函数。 因此,我想出了一个更简单的解决方案,即直接从函数getSessionUser中读取数据库。实际上,getEmail将在内部访问数据库,因此最终结果是相同的:

getSessionUser :: Handler User
getSessionUser = do
    mu <- maybeAuthId 
    case mu of
      -- redirect to the home page if we are not authenticated.
      Nothing -> redirect HomeR
      Just u  -> liftHandler $ runDB $
        textToUser . userFEmail . fromJust <$> get u

0 个答案:

没有答案