2013-01-24 3 views
4

내 코드에서이 클래스와 비슷한 것을 가지고 있습니다. 내 상황에 클래스 Foo에 또 다른 매개 변수로 '를 추가하는 것은 의미가 없습니다. Foo특정 예를 들어 내부 일치 유형에 대한 동의어/형식 동의어의 패턴 일치

class Foo a where 
    type FCtx a a' :: Constraint 
    type FCtx a a' =() 

    f :: (FCtx a a') => a -> a' 

data D b = D b 

instance (Integral b) => Foo (D b) where 
    -- the next line does not compile because b' does not appear on the LHS 
    type FCtx (D b) a' = (a' ~ D b', Integral b') 

    f (D x) = D $ fromIntegral x 

, 나는 a'이 방법으로 관련이있는 것으로합니다.

class DClass d where 
    type DType d 

instance DClass (D b) where 
    type DType (D b) = b 

Foo 인스턴스가 지금이된다 :

instance (Integral b) => Foo (D b) where 
    type FCtx (D b) a' = (a' ~ D (DType a'), Integral (DType a')) 
    f (D x) = D $ fromIntegral x 

은이 작품을 만들기 위해 내가 함께 왔어요 유일한 방법은 "명백한"유형의 동의어로 "더미"클래스를 추가하는 것입니다 문제는 (D b)가 b를 결정하는 타입 동의어/함수 종속성을 표현하기 위해 특정 데이터 유형에 대한 전체 클래스 (및 인스턴스)를 작성해야한다는 것입니다. 항상D b의 형식 매개 변수를 의미하기 때문에 DType a'이 필요하기 때문에이 클래스의 다른 인스턴스는 없습니다.

type DParam (D b) = b 

instance (Integral b) => Foo (D b) where 
    type FCtx (D b) a' = (a' ~ D (DParam a'), Integral (DParam a')) 
    f (D x) = D $ fromIntegral x 

또는 모든 유형의 동의어를 사용하지 않고이 제약을 표현 어쩌면 몇 가지 더 좋은 방법 : 내가 대신 할 싶은 무엇

은 같은 것입니다. 이 작업을 수행하기 위해 단일 인스턴스와 타입 동의어로 (개방형) 클래스를 만들어야하고, 다른 사람들이 의도하지 않은 새 인스턴스를 잠재적으로 만들 수 있다고하는 것은 안전하지 않은 것처럼 보입니다.

적어도 패턴 일치 유형 동의어를 위의 클래스/인스턴스 DClass으로 바꾸는 표준 방법이 없을까요?

+0

당신은 항상 당신이 만든 타입의 클래스를 내보낼 수 없습니다. – Satvik

+0

사실입니다. 나는 단지 더 가벼운 솔루션을 찾고있다. – crockeea

+1

올바르게 기억한다면 클래스가 내보내기 목록에 있는지 여부에 관계없이 클래스 가져 오기를 입력하십시오. – vivian

답변

5

약간 가벼운 무게, 사용 형 가족 :

type family DParam d :: * 
type instance DParam (D b) = b 

당신이 훨씬 더 지금 할 수 있다면 확실하지 ...