2010-12-10 8 views
7

que tienen dos tipos de datos simples en Haskell:¿Cuál es la "forma correcta" de usar tipos Haskell con datos anidados MongoDB?

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

Ignorando por un momento la falta de marcas de tiempo, y el uso de cuerdas frente a cadenas de bytes, simplemente quiero para almacenar los comentarios en MongoDB anidados en sus entradas.

Hasta ahora he estado usando un ejemplo bastante simple para almacenar datos:

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

La aplicación a continuación, se ve algo como esto:

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) 
se esperaría

Como, este se descompone en ("comments" =: tcomments a). Estoy seguro de que me estoy metiendo en un área de tipos Haskell en la que no tengo mi propio conocimiento, así que estoy emocionado de escuchar cómo otros se acercarían a esto.

Respuesta

8

También debe traducir documentos incrustados. Entonces

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) 

más la instancia similar para TicketComment.

También utilizaría el sinónimo tipo Document para [Field].

+0

Ugh ... tan simple. Gracias, no estoy seguro de por qué pensé que sería más complicado que eso. – clintm

2

Parece que las implementaciones transin y transout se han invertido en su instancia. Su transin toma un Ticket y devuelve una lista de Field s; pero ese es el tipo de transout.

+0

Oh, hey, tienes razón. Arreglando ahora. ¡Gracias! – clintm

Cuestiones relacionadas