2016-08-05 3 views
0

나는이 같은 유형의 "재료의 열"의 여러 유형에 대한 클래스, 그래서 뭔가를 만들려면 : 하스켈 : 데이터 여러 유형 변수에 대한 인스턴스?

class Column c where 
    at :: c a -> Int -> a 

data ListColumn a = ListColumn { 
    lcContent :: [a] 
} 

instance Column ListColumn where 
    at c i = lcContent c !! i 

가 지금은 서로 하나의 열을 도출하고자합니다. 고객 열이 있다고 가정 해 보겠습니다. 고객 이름의 열을 파생 시키려합니다. 그래서 내가 쓴 :

data DerivedColumn a b c = DerivedColumn { 
    dcBase :: c a, 
    dcDerive :: a -> b 
} 

a 고객되고, 위의 예에서 b 고객 이름.

instance Column (DerivedColumn a b) where 
    at c i = dcDerive c $ at (dcBase c) i 

그러나 GHC는 (Column should have kind * -> *, but DerivedColumn a b has kind (* -> *) -> *)를 좋아하지 않는 것 : 지금은 내가 이런 식으로 뭔가를 쓸 수 있다고 생각. 누군가 올바른 방향으로 가리킬 수 있습니까?

data DerivedColumn c a b = DerivedColumn { 
    dcBase :: c a, 
    dcDerive :: a -> b 
} 

instance Column c => Column (DerivedColumn c a) where 
    at dc i = dcDerive $ at (dcBase dc) i 

, 비트를 확장하려면 당신이 당신의 Column 클래스를 보면, 당신은 c 종류 * -> * 것을 볼 것이고, c aa가 있습니다 :

+0

정확히 무엇이 원하는지는 조금 불분명하지만 컨테이너 유형을 'a', 마지막으로 가지려면'DerivedColumn '의 유형 변수를 섞어 야 할 필요가있는 것 같습니다. 그래서 정의는'data DerivedColumn c b a = ...'이어야만합니까? 'Column' typeclass는 구체적인 타입을 얻기 위해 컨테이너 타입을 적용 할 수있는 타입을 기대합니다. –

+0

예, 감사합니다. 감사합니다. – martingw

답변

2

나는 당신이 대신 원하는 것은이 생각 c에 포함 된 값의 유형. DerivedColumn a b c에 포함 된 열의 값이 b이어야한다고 가정하므로 Column의 인스턴스를 정의하기 위해 유형 생성자에 전달하는 마지막 값이되어야합니다.

+0

고마워, 그게 빠르다. 이제는 효과가있다. 왜 이제야 그 이유를 알 수 있을까? -) ... – martingw

+0

몇 가지 설명을 추가했다. 질문이 있으면 알려주세요. – Emil