Как «правильно» использовать типы Haskell с вложенными данными MongoDB? - PullRequest
8 голосов
/ 10 декабря 2010

У меня есть два простых типа данных в 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). Я уверен, что попадаю в область типов Хаскелла, где мне не хватает моих собственных знаний, поэтому я рад услышать о том, как другие подойдут к этому.

Ответы [ 2 ]

8 голосов
/ 10 декабря 2010

Вы должны также переводить встроенные документы.Так что

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].

2 голосов
/ 10 декабря 2010

Похоже, что у вас просто реализации transin и transout в вашем экземпляре. Ваш transin берет Ticket и возвращает список Field с; но это тип transout.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...