2011-05-11 20 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