Сериализуемое представление типа данных для проверки соответствия клиент-сервер

Для сервер-клиентского приложения мне нужен способ автоматически проверять соответствие структур данных, используемых для связи. Чтобы достичь этого, мне нужно сравнить сериализуемые представления этих структур данных. Что я в основном ожидаю, так это то, что построит дерево представления типов с примитивными типами в качестве листьев.

Например, тип Artist из следующей модели данных:

data Artist = Artist Text Genre
data Genre = Jazz | Metal

будет представлен как что-то вроде:

DataType 
  "Artist"
  [
    Constructor
      "Artist"
      [
        AbstractType "Data.Text.Text",
        DataType
          "Genre"
          [
            Constructor "Jazz" [],
            Constructor "Metal" []
          ]
      ]
  ]

Есть ли библиотека, которая реализует такую ​​функциональность, и есть ли лучшие подходы к этой проблеме? Например, как они подходят к этому в Cloud Haskell?

3 ответа

Решение

Я только что выпустил библиотеку структуры типов, которая подходит именно к проблеме, заявленной в теме. Он создает представление данных типа, проходя все типы, на которые ссылается, вплоть до примитивов. Таким образом, он транзитивно фиксирует изменения для всех задействованных типов, которые могут даже поступать из разных библиотек.

Полученный график имеет Hashable Например, он может быть использован для выполнения сопоставления. Например, с его помощью можно создать хеш-версию.

Теперь, так как реализация использует классы типов с реализациями CAF, построение данных представления должно быть выполнено в O(1). Я должен упомянуть, однако, что я не тестировал это.

Кстати, поскольку типы могут быть рекурсивными, библиотека не может быть реализована так, как ожидалось в вопросе, потому что иначе она создаст бесконечное дерево. Вместо этого библиотека представляет структуру данных в виде графика. На самом деле этот граф представлен в виде словаря ребер, поскольку лучшего способа представить неизменный граф не существует.

Как пользоваться

Вот сеанс GHCi, показывающий, как предполагается использовать библиотеку:

λ>import TypeStructure 

Построение графа представления структуры типа:

λ>graph (undefined :: Int)
(Type_Con ("GHC.Types","Int"),[(("GHC.Types","Int"),Declaration_ADT [] [("I#",[Type_Con ("GHC.Prim","Int#")])]),(("GHC.Prim","Int#"),Declaration_Primitive)])

Графики разных типов гарантированно будут разными:

λ>graph (undefined :: Int) /= graph (undefined :: Integer)
True

Графики значений одного типа гарантированно будут одинаковыми:

λ>graph True == graph False
True    

Получение хеша типовой структуры:

λ>import Data.Hashable
λ>hash $ graph (undefined :: Int)
3224108341943761557

Хэши разных типов не должны быть равны:

λ>(hash $ graph (undefined :: Int)) /= (hash $ graph (undefined :: Integer))
True

Наша универсальная библиотека сериализации делает это (в противном случае это аналогичная функция cereal или же binary). Ищите функцию typeSign, По умолчанию encode / decode пара не делает подписи типа, но encodeLive будет, или вы можете подписать типы данных самостоятельно.

В качестве решения на основе SYB есть библиотека typehash, которая генерирует хеши структуры типов с использованием Data пример.

Другие вопросы по тегам