2010-12-10 11 views
7

Ich habe zwei einfache Datentypen in Haskell:Was ist der richtige Weg, um Haskell-Typen mit verschachtelten MongoDB-Daten zu verwenden?

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

für einen Moment Ignorieren der Mangel an Zeitstempel und die Verwendung von Strings vs. bytestrings, habe ich einfach die Kommentare in MongoDB in ihre Tickets verschachtelt gespeichert werden sollen.

Bis jetzt habe ich ein ziemlich einfaches Beispiel unter Verwendung von Daten zu speichern:

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

Die Umsetzung dann etwa wie folgt aussieht:

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) 

Wie zu erwarten, diese bricht an ("comments" =: tcomments a). Ich bin zuversichtlich, dass ich in einen Bereich von Haskell-Typen vorsteige, in denen mein eigenes Wissen fehlt. Ich bin gespannt, wie andere sich diesem Thema nähern.

Antwort

8

Sie müssen auch eingebettete Dokumente übersetzen. So

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) 

und ähnliches Beispiel für TicketComment.

Auch ich würde das Typensynonym Document für [Field] verwenden.

+0

Ugh ... so einfach. Danke, nicht sicher, warum ich dachte, es wäre komplizierter. – clintm

2

Es sieht so aus als ob Sie die transin und transout Implementierungen in Ihrer Instanz umgekehrt haben. Ihr transin nimmt eine Ticket und gibt eine Liste Field s zurück; aber das ist transout 's Typ.

+0

Oh, hey, du hast Recht. Fixiere es jetzt. Vielen Dank! – clintm

Verwandte Themen