2010-12-10 51 views
7

我在Haskell兩個簡單數據類型:什麼是使用Haskell類型與MongoDB嵌套數據的「正確方法」?

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的類似情況。

另外,我會使用類型同義詞Document[Field]

+0

呃......太簡單了。謝謝,不知道爲什麼我認爲它會比這更復雜。 – clintm 2010-12-11 04:40:42

2

看起來你只是在實例中反轉了transintransout實現。您的transin需要Ticket並返回一個Field s的列表;但這是transout的類型。

+0

哦,嘿,你是對的。現在修復它。謝謝! – clintm 2010-12-10 19:50:23

相關問題