2010-12-10 2 views
7

나는 Haskell에서 두 개의 간단한 데이터 타입을 가지고있다.MongoDB 중첩 된 데이터로 Haskell 타입을 사용하는 '올바른 방법'은 무엇입니까?

data Ticket = Ticket { 
    tbody :: String, 
    tauthor :: String, 
    tcomments :: [TicketComment] 
} 
data TicketComment = TicketComment { 
    tcbody :: String, 
    tcauthor :: String 
} 

타임 스탬프가 부족하고 문자열과 바이트를 사용하는 것을 무시하고 단순히 티켓에 중첩 된 MongoDB에 주석을 저장하기 만하면된다.

지금까지 데이터를 저장하는 데 오히려 간단한 인스턴스를 사용했습니다.

class MongoIO a where 
    transout :: a -> [Field] 
    transin :: [Field] -> (Maybe a) 

다음과 같은 구현이 나타납니다.

instance MongoIO Ticket where 
    transout a = [("body" =: tbody a), 
       ("author" =: tauthor a), 
       ("comments" =: tcomments a)] 
    transin a = case (,,) <$> look "body" a 
         <*> look "author" a 
         <*> look "comments" a of 
       Nothing -> Nothing 
       Just (bo,au,co) -> 
        Just $ Ticket (typed bo) (typed au) (typed co) 

예상대로 이것은 다음과 같습니다. ("comments" =: tcomments a). 나는 내 자신의 지식이 부족한 Haskell 타입의 영역에 들어가고 있다고 확신하므로 다른 사람들이 어떻게 접근 할 것인지 듣게되어 기쁩니다.

답변

8

또한 임베디드 문서도 번역해야합니다. 그래서

instance MongoIO Ticket where 
    transout t = [ 
    "body" =: tbody t, 
    "author" =: tauthor t, 
    "comments" =: map transout (tcomments t) ] 
    transin d = Ticket 
    <$> lookup "body" d 
    <*> lookup "author" d 
    <*> (mapM transin =<< lookup "comments" d) 

플러스 TicketComment 비슷한 인스턴스입니다.

또한 [Field]에 대해서는 동의어 Document을 사용합니다.

+0

어 ... 아주 간단합니다. 고맙습니다, 왜 내가 그게 더 복잡 할거라고 생각하는지 모르겠군요. – clintm

2

예를 들어 transintransout 구현이 반전 된 것으로 보입니다. transinTicket이며 Field의 목록을 반환합니다. 하지만 transout 님의 유형입니다.

+0

아, 네 말이 맞아. 지금 고치세요. 감사! – clintm

관련 문제