2013-07-24 4 views
1

나는 일반적인 정보를 저장하는 유형을 만들고 싶습니다. 저로서는이 유형이 입니다. 여기 분자는 화학적 그래프와 분자 속성을 저장합니다. 플로트, INT, 문자열 e.t.c. :하스켈 일반 데이터 구조

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

속성 나는 속성이 어떤 유형이있을 수 있기 때문에 튜플

type Property a = (String,a) 

으로 대표 할


질문은 분자 데이터 구조를 구성하는 방법입니다. 그래서 분자에서 임의의 유형의 속성 수를 수집 할 수 있습니다. 내가 할 경우

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

psudo-dynamic 타이핑 솔루션을 보려면 Data.Dynamic을 참조하십시오.