2013-07-24 50 views
1

我想創建一個類型來存儲一些通用信息,對於我來說,這個類型是 分子,其中我存儲化學圖和分子屬性。Haskell通用數據結構

data Molecule = Molecule { 
    name :: Maybe String, 
    graph :: Gr Atom Bond, 
    property :: Maybe [Property] -- that's a question 
} deriving(Show) 

屬性我要代表作爲元組

type Property a = (String,a) 

因爲一個屬性可能具有任何類型:float,INT,字符串e.t.c.


的問題是如何形成的分子數據結構,所以我將能夠收集任何類型的分子特性的任何數字。如果我做

data Molecule a = Molecule { 
    name :: Maybe String, 
    graph :: Gr Atom Bond, 
    property :: Maybe [Property a] 
} deriving(Show) 

我必須直接指定一種類型,當我創建一個分子。

+6

這裏的問題是(總是)像這樣:你想要做什麼*做一個屬性?假設你可以在其中放置任何類型。現在你有一個任何東西的列表。你通常對這樣的列表做什麼? –

回答

3

如果事先知道組屬性的分子可能有,你可以定義和類型:

data Property = Mass Float | CatalogNum Int | Comment String 

如果你想要這個類型是可擴展的,你可以使用Data.Dynamic作爲另一個答案提示。例如:

data Molecule = Molecule { name :: Maybe String, 
          graph :: Gr Atom Bond, 
          property :: [(String,Dynamic)] 
         } deriving (Show) 

mass :: Molecule -> Maybe Float 
mass m = case lookup "mass" (property m) of 
      Nothing -> Nothing 
      Just i -> fromDynamic i 

你也可以擺脫「stringly類型的」 (String,a)對,說:

-- in Molecule: 
-- property :: [Dynamic] 

data Mass = Mass Float 

mass :: Molecule -> Maybe Mass 
mass m = ... 

這些嘗試都沒有給過,因爲剛剛解析出的(String,String)對多類型安全沒有辦法強制用戶創建格式良好的屬性(缺少新類型的包裝屬性,並將構造函數隱藏在另一個模塊中,這再次破壞了可擴展性)。

你可能想要的是Ocaml風格的多態變體。你可以看看Vinyl,它提供了類型安全的可擴展記錄。另一方面,您可能希望擺脫圍繞屬性列表的Maybe包裝,因爲空列表已經編碼了沒有屬性的情況。

0

你可能想看看Data.Dynamic爲psudo動態打字解決方案。