2017-12-05 9 views
0

에 맞게 :는 어떻게이 같은 유형

infixr 9 ||| 
data a ||| b = A a|B b deriving (Eq, Data, Show) 

class IsTag a where 
    anyTag :: a 

내가 예를 들어, IsTag의 인스턴스이 a|||b 일부 값, 유지 : A (B (A x)) - 중첩의 깊이가 하나가 될 수 있습니다, 확인합니다. 그리고 나는 xanyTag과 동등하다는 것을 감지하는 함수를 작성하고자하므로 a|||b을 취하고 Bool - x의 인스턴스의 anyTag과 같은 기저 값 (예제에서는 x)을 반환합니다. 그러한 함수를 작성하는 방법? 나는 "무한 타입"과 같은 에러로 인해 패턴 매칭을 할 수 없다. 을 a|||b에 추가하고 x 타입을 Data에서 사용할 수 있기를 바라지 만 어떻게 이해할 수 없다. 이러한 재귀 유형을 통해 배/트래버스.

+3

작성할 수있는 코드 종류의 최소한의 완벽한 예제를 추가 할 수 있습니까? 실제 문제를 해결하는 데 도움이 될 것입니다. –

+0

[여행 시작] (https://stackoverflow.com/questions/47577470/read-of-types-sum). 이 태그는 일반적인 읽기/일치/표시와 함께 다양한 유형의 태그입니다. 모든 것이 좋고 과제가 해결되었지만 [tag1, tag2] 및 [tag1, anyTag]와 같은 태그가 일치 할 경우를 구별해야합니다. (이것은 의사 코드입니다.) 가장 적합한 경우를 알기 위해 케이스). 그래서, 그 태그 유형 ('a ||| b')이'== anyTag' –

답변

2

그것은 이것보다 훨씬 더 얻을 수 없습니다 :

{-# LANGUAGE DefaultSignatures #-} 
class IsAnyTag a where 
    isAnyTag :: a -> Bool 
    default isAnyTag :: (Eq a, IsTag a) => a -> Bool 
    isAnyTag = (anyTag ==) 

instance (IsAnyTag a, IsAnyTag b) => IsAnyTag (a ||| b) where 
    isAnyTag (A a) = isAnyTag a 
    isAnyTag (B b) = isAnyTag b 

-- and one more line of `instance IsAnyTag X` for each `X` that 
-- is an instance of `IsTag` 

여기에 주요 단점이가 |||의 양쪽에있는 유형은 당신이 테스트에도 불구하고, IsAnyTag 인스턴스가해야 할 것을 요구한다는 것입니다 한쪽 만. 그것들은 정적 유형 검사를 통해 중단됩니다.