2012-11-21 3 views
1

Yesod를 사용하여 모든 페이지의 탐색 모음에 사용자의 프로필 이름을 표시하고 ProfileId과 연결된 프로필 페이지를 표시하려고합니다. Foundation.hs에서리팩토링 어쩌면 스택 Yesod

User 
    ident Text 
    password Text Maybe 
    UniqueUser ident 
Profile 
    username Text 
    user UserId 
    UniqueProfile user 
    UniqueUsername username 

발췌문 : config/models이 포함 나는 프로필 조회 할 수 있습니다 사용자 ID와

defaultLayout widget = do 
    master <- getYesod 
    mmsg <- getMessage 
    maid <- maybeAuthId 

하지만 Maybe들에 묻혀있다. This Stack Overflow question은 모두 Maybe을 처리하는 좋은 힌트를 제공합니다. 그러나 하스켈의 저의 작은 경험으로, 저는 여전히 그것에 고심하고 있습니다.

내가 해낸 :

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 

이 작동하지만, 최적이 아닌 - 반복 코드와 더블베이스 안타. 이 코드를 어떻게 리팩토링 할 수 있습니까? 아아, A는 더 - 이동

(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; 
              .... }; 
      .... } 

내가 오류를 이해하지만, 나는 그것을 해결하지 않는

나는이 일 것이라고 생각하지 않습니다.

깨닫게하십시오!

답변

3

결과를 (Maybe a, Maybe b) 인 것처럼 바인딩하려고하지만 실제로는 Maybe (a, b)입니다.

당신은 충분히 쉽게 변환 할 수 있습니다 :

unpairMaybe :: Maybe (a, b) -> (Maybe a, Maybe b) 
unpairMaybe (Just (x, y)) = (Just x, Just y) 
unpairMaybe Nothing  = (Nothing, Nothing) 

다음이 작동합니다 : `unpairMaybe 그냥 (X, Y :

하지만, 일
(mpid, mprofilename) <- liftM unpairMaybe $ runMaybeT $ do 
       ouid <- MaybeT maybeAuthId 
       (Entity pid p) <- MaybeT . runDB . getBy $ UniqueProfile ouid 
       return (pid, profileUsername p) 
+0

, 나는 그것을 조금 변경해야) = (그냥 x, 그냥 y)' 여분의 괄호가 필요합니다 : 'unpairMaybe (그냥 (x, y)) = (그냥 x, 그냥 y)'. – davidbe

+0

죄송합니다. 너무 빨리 입력해야합니다. 나는 지금 그 줄을 고쳤다. – dave4420