简体   繁体   中英

Haskell generic data structure

I want to create a type to store some generic information, as for me, this type is Molecule, where i store chemical graph and molecular properties.

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

Properties I want to represent as tuple

type Property a = (String,a)

because a property may have any type: Float, Int, String etc


The question is how to form Molecule data structure, so I will be able to collect any numbers of any types of properties in Molecule. If I do

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

I have to diretly assign one type when I create a molecule.

If you know in advance the set of properties a molecule might have, you could define a sum type:

data Property = Mass Float | CatalogNum Int | Comment String

If you want this type to be extensible, you could use Data.Dynamic as another answer suggests. For instance:

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

You could also get rid of the "stringly-typed" (String,a) pairs, say:

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

data Mass = Mass Float

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

Neither of these attempts gives much type safety over just parsing out of (String,String) pairs since there is no way to enforce the invariant that the user creates well-formed properties (short of wrapping properties in a new type and hiding the constructors in another module, which again breaks extensibility).

What you might want are Ocaml-style polymorphic variants. You could look at Vinyl , which provides type-safe extensible records.

As an aside, you might want to get rid of the Maybe wrapper around the list of properties, since the empty list already encodes the case of no properties.

您可能希望查看Data.Dynamic以获取psudo动态类型解决方案。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM