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

Nik*_*kov 5 haskell

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

例如,Artist以下数据模型中的类型:

data Artist = Artist Text Genre
data Genre = Jazz | Metal
Run Code Online (Sandbox Code Playgroud)

将表示为:

DataType 
  "Artist"
  [
    Constructor
      "Artist"
      [
        AbstractType "Data.Text.Text",
        DataType
          "Genre"
          [
            Constructor "Jazz" [],
            Constructor "Metal" []
          ]
      ]
  ]
Run Code Online (Sandbox Code Playgroud)

是否有任何库实现了这样的功能,有没有更好的方法来解决这个问题?例如,他们如何在Cloud Haskell中解决这个问题?

Nik*_*kov 2

我刚刚发布了一个类型结构库,它完全解决了主题中声明的问题。它构造类型的数据表示,同时遍历它引用的所有类型直至基元。因此,它可以传递捕获所有涉及的类型的更改,这些更改甚至可能来自不同的库。

\n

生成的图有一个Hashable实例,因此它也可以用于执行匹配。例如,可以用它生成一个“版本”散列。

\n

现在,由于实现使用带有 CAF 实现的类型类,因此表示数据的构造应该在 O(1) 内完成。但我必须指出,我还没有对它进行基准测试。

\n

顺便说一句,由于类型可以递归,因此该库无法按照问题中预期的方式实现,因为否则它将构造一个无限树。相反,该库将数据结构表示为图形。事实上,该图本身表示为边字典,因为没有更好的方法来表示不可变图。

\n

如何使用

\n

这是一个 GHCi 会话,显示了应该如何使用该库:

\n
\xce\xbb>import TypeStructure \n
Run Code Online (Sandbox Code Playgroud)\n

类型结构表示图的构建:

\n
\xce\xbb>graph (undefined :: Int)\n(Type_Con ("GHC.Types","Int"),[(("GHC.Types","Int"),Declaration_ADT [] [("I#",[Type_Con ("GHC.Prim","Int#")])]),(("GHC.Prim","Int#"),Declaration_Primitive)])\n
Run Code Online (Sandbox Code Playgroud)\n

不同类型的图保证是不同的:

\n
\xce\xbb>graph (undefined :: Int) /= graph (undefined :: Integer)\nTrue\n
Run Code Online (Sandbox Code Playgroud)\n

相同类型的值的图保证是相同的:

\n
\xce\xbb>graph True == graph False\nTrue    \n
Run Code Online (Sandbox Code Playgroud)\n

获取类型结构的哈希值:

\n
\xce\xbb>import Data.Hashable\n\xce\xbb>hash $ graph (undefined :: Int)\n3224108341943761557\n
Run Code Online (Sandbox Code Playgroud)\n

不同类型的哈希值不应该相等:

\n
\xce\xbb>(hash $ graph (undefined :: Int)) /= (hash $ graph (undefined :: Integer))\nTrue\n
Run Code Online (Sandbox Code Playgroud)\n