用于客户端 - 服务器一致性检查的数据类型的可序列化表示

时间:2014-03-28 14:25:41

标签: haskell

对于服务器 - 客户端应用程序,我需要一种方法来自动检查用于通信的数据结构的一致性。为此,我需要比较这些数据结构的可序列化表示。我基本上期望的是构造一个类型表示树,其基本类型为叶子。

,例如,来自以下数据模型的类型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 个答案:

答案 0 :(得分:2)

我刚刚发布了一个type-structure库,它完全接近主题中声明的问题。它构造一个类型的数据表示,同时遍历它引用的所有类型到基元。因此,它可以传递地捕获所涉及的所有类型的变化,甚至可能来自不同的库。

生成的图形具有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

答案 1 :(得分:1)

我们的通用序列化库beamable执行此操作(否则它与cerealbinary的功能类似)。寻找函数typeSign。默认的encode / decode对不会进行类型签名,但会encodeLive,或者您可以自行签署数据类型。

答案 2 :(得分:1)

作为基于SYB的解决方案,有一个typehash库,它使用Data实例生成类型结构的哈希值。