What is the “right way” to use Haskell types with MongoDB nested data?

Haskell has two simple data types:

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

Ignoring for some time the lack of timestamps and the use of strings or bytes, I just want to save the comments in MongoDB embedded in their tickets.

So far I have used a fairly simple instance to store data:

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

The implementation then looks something like this:

 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) 

As expected, this breaks down into ("comments" =: tcomments a) . I am sure that I fall into the field of Haskell types, where I lack my own knowledge, so I am glad to hear about how others approach this.

+7
mongodb haskell
source share
2 answers

You also need to translate the attached documents. 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) 

plus a similar instance for TicketComment .

I would also use a synonym of type Document for [Field] .

+8
source share

It looks like you just implemented the transin and transout in your instance. Your transin accepts a Ticket and returns a list of Field s; but this type of transout .

+2
source share

All Articles