[Haskell] Бинарная сериализация
От: Tonal- Россия www.promsoft.ru
Дата: 03.02.10 09:43
Оценка:
Попробовал написать сериализацию с помощью Data.Binary и наткнулся на бяку при рекурсивных данных.
data A = A {a_unuqId :: Int, a_refs :: [B]}
data B = B {b_unuqId :: Int, b_refs :: [A]}

saveABtoFile :: FilePath -> ([A], [B]) -> IO ()
saveABtoFile = Data.Binary.encodeFile

loadABfromFile :: FilePath -> IO (([A], [B]))
loadABfromFile = Data.Binary.decodeFile

С сохранением всё ясно, вместо сохранения списка ссылок сохраняем список id-ов:
instance Binary A where
  put (A i refs) = put i >> put (map b_unuqId refs)

А вот как написать get?
Можно конечно написать как-то так:
instance Binary A where
  get = do
    i <- get
    b_ids <- get
    return $ A i (map (\bi -> B bi []) b_ids

loadABfromFile = do
  (xa, xb) <- Data.Binary.decodeFile
  let xa' = map createA xa
      xb' = map createB xb
      createA (A i refs) = A i $ map (\b -> fromJast . find (== (b_unuqId b)) $ xb') refs
      createB (B i refs) = B i $ map (\a -> fromJast . find (== (a_unuqId a)) $ xa') refs
  return (xa', xb')

Но как-то это некрасиво...

Есть ещё какие-нибудь способы?
Или лучше сразу хранить id-ешки и при необходимости шерстить соответствующий список/мап/хешь?

П. С. Нашел ссылки на несколько библиотек сериализации. Некоторые умеют вроде сами такое разруливать. А Булатовская по описанию страшно быстрая и автоматом строит инстансы.
Но кроме Data.Binary нет ни одной живой.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.