2011-05-11 73 views
4

说,我有很长的数据结构定义通用性但安全性选择哪种数据结构?

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

现在我有3项任务:

  1. 创建像一个的实例草案{X1 = “这是X1”,...}
  2. 从一些其他数据结构创建一个实例
  3. 从甲
实例创建另一个数据实例

这三项任务涉及对标签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映射到那些中间形式的数据;我需要将这些表单数据映射到实际的表单文本表示;我需要创建草稿中间表单数据。一方面,我讨厌重复那些数据标签,另一方面它让我感到安全,我不会在映射时混淆任何标签。有没有银子弹?

+1

相同类型(例如列表)的数据结构的所有元素,并且它们是否仅通过其索引进行区分?标签的数量有多重要? – 2011-05-11 07:57:42

+0

标签的数量是有意义的,因为目前我必须在我的代码中至少复制大量数据标签3次。而且我基本上还需要在草稿模式中重复标签名称。 – LennyStackOverflow 2011-05-11 08:18:40

+0

如何使用SYB或Uniplate?此外,您可能会在GHC中使用RecordWildcards扩展程序获得一些里程。 (发布大部分程序可能会对此有所帮助) – aleator 2011-05-11 09:16:40

回答

3

像这样深度结构化的数据在Haskell中最为惯用地表达为嵌套的代数数据类型,就像你所做的一样。为什么?它给数据提供了最多的类型结构和安全性,防止功能将数据放入错误的格式。通过对某些类型进行新的分类,可以获得进一步的安全性,从而增加每个领域的数据之间的差异。

但是,像这样的非常大的ADT可能难以用名称和操作。编译器设计中的一个常见情况就是指定这样一个大的ADT,并且为编译器编写代码,我们倾向于使用大量的通用编程技巧:SYB,元编程,甚至是模板Haskell,来生成所有的我们需要的样板。因此,总而言之,我会保留你正在使用的ADT方法,但看看使用泛型(例如SYB或模板Haskell)来生成一些定义和辅助函数。

+0

好的,谢谢。将尝试理解syb。 – LennyStackOverflow 2011-05-12 06:51:25