使用 Yesod,我想在每个页面的导航栏中显示用户的个人资料名称,并希望使用 链接ProfileId
到用户的个人资料页面。config/models
包含:
User
ident Text
password Text Maybe
UniqueUser ident
Profile
username Text
user UserId
UniqueProfile user
UniqueUsername username
片段来自Foundation.hs
:
defaultLayout widget = do
master <- getYesod
mmsg <- getMessage
maid <- maybeAuthId
使用用户 ID,我可以查询配置文件,但它被埋在Maybe
s 中。
这个 Stack Overflow 问题很好地提示了如何处理所有这些问题Maybe
......但是,凭借我对 Haskell 的一点经验,我仍然在努力解决它。
我想出了:
mpid <- runMaybeT $ do
ouid <- MaybeT maybeAuthId
(Entity pid _) <- MaybeT . runDB . getBy $ UniqueProfile ouid
return pid
mprofilename <- runMaybeT $ do
ouid <- MaybeT maybeAuthId
(Entity _ p) <- MaybeT . runDB . getBy $ UniqueProfile ouid
return $ profileUsername p
这可行,但不是最佳的 - 重复代码和双重数据库命中。如何重构此代码?
我认为这会起作用:
(mpid, mprofilename) <- runMaybeT $ do
ouid <- MaybeT maybeAuthId
(Entity pid p) <- MaybeT . runDB . getBy $ UniqueProfile ouid
return (pid, profileUsername p)
但是,唉,不行:
Foundation.hs:91:9:
Couldn't match expected type `Maybe (t0, Text)'
with actual type `(t1, t2)'
In the pattern: (mpid, mprofilename)
In a stmt of a 'do' block:
(mpid, mprofilename) <- runMaybeT
$ do { ouid <- MaybeT maybeAuthId;
(Entity pid p) <- MaybeT . runDB . getBy $ UniqueProfile ouid;
return (pid, profileUsername p) }
In the expression:
do { master <- getYesod;
mmsg <- getMessage;
maid <- maybeAuthId;
(mpid, mprofilename) <- runMaybeT
$ do { ouid <- MaybeT maybeAuthId;
(Entity pid p) <- MaybeT . runDB . getBy
$ UniqueProfile ouid;
.... };
.... }
我理解错误,但我没有解决它。
开导我!