【发布时间】:2011-05-12 00:04:35
【问题描述】:
假设我有一个很长的数据结构定义
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 映射到那些中间表单数据;我需要将这些表单数据映射到实际的表单文本表示;我需要创建草稿中间表单数据。一方面我讨厌重复这些数据标签,另一方面它给了我安全感,我在映射时不会混淆任何标签。有灵丹妙药吗?
【问题讨论】:
-
数据结构的所有元素是否都属于同一类型(例如列表),它们是否都仅通过索引来区分?标签的数量是否重要?
-
标签的数量之所以重要,是因为目前我必须在我的代码中复制大量数据标签至少 3 次。而且我在草稿模式下也基本上需要重复标签名称。
-
使用SYB或Uniplate怎么样?此外,您可能会在 GHC 中使用 RecordWildcards 扩展获得一些里程。 (在这里发布你的大部分程序可能会有所帮助)
-
如果我理解正确 - 我觉得,您使用
data-type 保存数据标签的解决方案过于静态。为什么不使用 Data.Map 来组织这些标签,将它们映射到 Array 或 List 的索引? -
@phynfo:列表的缺点是很容易混淆元素的顺序和含义。使用地图,您可能会以与数据结构标签相同的方式重复键。 :(
标签: data-structures haskell types