数据结构 – 选择通用性但安全性的数据结构是什么?

假设我有一个很长的数据结构定义

data A = A {
  x1 :: String
, x2 :: String
...
, x50 :: String
}

现在我有3个任务:

>创建A的草稿实例,如A {x1 =“this is x1”,…}
>从其他一些数据结构创建A的实例
>从A的实例创建另一个数据实例

这三个任务涉及标签x1,…,x50的繁琐复制.
更好的解决方案是通用列表

[
  Foo "x1" aValue1
, Foo "x2" aValue2
...
]

因为它会使遍历和创建草稿变得更容易(列表定义已经是草案).缺点是将其他数据结构映射到此处会更危险,因为您丢失了静态类型检查.

这有意义吗?
有通用但安全的解决方案吗?

编辑:为了给你一个更好的想法,它是关于将业务数据映射到文本表示,如表单和字母.例如.:

data TaxData = TaxData {
  taxId :: String
, income :: Money
, taxPayed :: Money,
, isMarried :: Bool
...
}


data TaxFormA = TaxFormA {
  taxId :: Text
, isMarried :: Text
  ...
}
data TaxFormB = TaxFormB {
  taxId :: Text
, taxPayedRounded :: Text
...
}

那些被转换成文本流,代表实际的形式.如果我将在一次通过中创建一个来自税收数据的表格,并且明年任何表格字段都会移动,那么例如是一个迷路的“0.0”,我不知道它属于哪里.这就是中间数据结构的用途:它可以轻松创建草稿数据.

所以我需要将实际的TaxData映射到那些中间表单数据;我需要将这些表单数据映射到实际的表单文本表示;我需要创建草稿中间表格数据.一方面我讨厌重复这些数据标签,另一方面它给了我安全,我不会在映射时混淆任何标签.有银弹吗?

最佳答案
像这样的深层次结构化数据在Haskell中作为嵌套的代数数据类型最常用地表达,就像你所做的那样.为什么?它为数据提供了最多的类型结构和安全性,防止功能将数据放入错误的格式.通过对某些类型进行newtyping可以获得进一步的安全性,以增加每个字段中数据之间的差异.

然而,像这样的非常大的ADT可能难以命名和操纵.例如,编译器设计的一个常见情况是指定如此大的ADT,并且为了帮助编写编译器的代码,我们倾向于使用许多通用编程技巧:SYB,元编程,甚至模板Haskell,以生成所有我们需要的样板.

总而言之,我会保留你正在采用的ADT方法,但是看看使用泛型(例如SYB或Template Haskell)来生成一些定义和辅助函数.

转载注明原文:数据结构 – 选择通用性但安全性的数据结构是什么? - 代码日志