Используя 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
С идентификатором пользователя я могу запросить профиль, но он скрыт в Maybe
s. Этот вопрос о переполнении стека дает хороший совет, как справиться со всеми этими Maybe
s... но , с моим небольшим опытом работы с 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;
.... };
.... }
Я понимаю ошибку, но не могу ее решить.
Просветите меня!