2017-05-15 8 views
3

불쌍한 영어에 대해 죄송합니다. 제목은 내가 의미하는 바를 설명하지 못할 수도 있습니다.유도하지 않고 Eq를 인스턴스화하는 방법

는 Data.Tree에서 Tree는 다음과 같이 정의된다 :이

-- | Multi-way trees, also known as /rose trees/. 
data Tree a = Node { 
     rootLabel :: a,   --^label value 
     subForest :: Forest a --^zero or more child trees 
    } 
#ifdef __GLASGOW_HASKELL__ 
    deriving (Eq, Read, Show, Data) 
#else 
    deriving (Eq, Read, Show) 
#endif 

그것은 인스턴스 ==-derivingTree (날짜)에 대한 /= 이용한다.

도출하지 않고도 동일한 작업을 수행 할 수 있습니까? 다음과 같이 시도해 보겠습니다.

data Test a = Test a 
instance Eq Test where 
    (Test a) == (Test b) = a == b 

하지만 예외가 발생합니다. 그 이유는 a와 b의 유형에 관한 것이라고 생각합니다.

==으로 데이터에 대한 맞춤 작업을 정의할지 여부는 무엇을 할 수 있습니까?

나는 Functorfmap을 사용할 수 있음을 알고 있습니다. 하지만 ==a == b과 같이 사용하려면 a = Test 1b = Test "a"이 필요합니다. 가능한가?

답변

9

당신 instanceTree 또는 TestEq의를 정의 할 수 있지만, 당신의 정의와 일부 문제가있다.

instance Eq Test where 
    (Test a) == (Test b) = a == b 

제 한 Eq TestTest여전히를 매개 변수화는 것이다. 실제로 data Test a = ...을 작성하면 유형 매개 변수가 있음을 의미합니다. EqTest a에 대해 정의되어

instance Eq (Test a) where 
    (Test y) == (Test x) = x == y

이제 이렇게 지정 : 그래서 당신은 그것을 지정할 수 있습니다. abxy으로 바 꾸었습니다. "type world"와 "variable world"가 분리되어 있기 때문에 이것은 필요하지 않지만 상황을 혼동시키지 않습니다.

그러나 여전히 문제가 있습니다 : x == y으로 전화하십시오. 그러나 a 그 자체가 Eq의 인스턴스라는 guantee가 없습니다. 당신은 따라서 형 제약와 함께 작동해야합니다

instance Eq a => Eq (Test a) where 
    (Test y) == (Test x) = x == y

지금 당신이 Test a뿐만 아니라 Eq의 인스턴스 Eq a 경우의 인스턴스로 지정.

instance (Eq a, Eq (Forest a)) => Eq (Tree a) where 
    (Tree x1 y1) == (Tree x2 y2) = x1 == x2 && y1 == y2 

는 (물론 내가 여기 당신이 평등을 정의하도록 두 나무가 동일한 방법이 가능하다 정의 : 당신의 Tree 데이터 구조에 대한

, Eqinstance 따라서 같아야합니다 (의미 상) 다른 방식으로 두 나무를 넘기 때문에 그 자체로는 사본에이 코드를 붙여 넣지 마십시오. @luqui 말한다처럼 - - instance Eq a => Eq [a]가 보유하고 있기 때문에 type Forest a = [Tree a] 경우, 당신은 Eq (Forest a) 유형의 제약 조건을 생략 할 수 있음을

참고. 따라서 그 경우 :

instance Eq a => Eq (Tree a) where 
    (Tree x1 y1) == (Tree x2 y2) = x1 == x2 && y1 == y2 
+1

N.B. 'Forest a'는'[a]'와 동의어이기 때문에 기술적으로'Eq (a)'를 의미하기 때문에'Eq (Forest a)'제약 조건은 필요하지 않습니다. 그러나이 대답은 질문의 매개 변수를 고려할 때 분명합니다. – luqui

+0

@luqui : 당신 말이 맞아요. 나는 숲이'[Tree a]'로 정의 된 것을 알지 못했다. (몇몇 추가적인 필드가 추가되었을 가능성이있다.) 나는 당신의 쪽지를 몇 가지 덧글과 함께 답안에 추가했습니다. 감사! –

+1

마지막 두 인스턴스는'Eq (Tree a)'에'Eq'가 없습니다. – chi