2016-11-19 2 views
0

하스켈에서 숫자 표현을위한 몇 가지 사용자 지정 데이터 형식을 만들었으니 이제는 EQ 인스턴스를 구현하고 싶지만 어쨌든 나는 갇혀있다. 그래서 난 이미 만든 :하스켈에서 사용자 정의 데이터 형식에 대한 인스턴스 생성하기

instance (Eq Sign) => Eq (Numeral) where 
(==) Num(x,_)== Num(y,_) = x==y 

그러나 나는이 오류가 : 패턴 구문 분석 오류 :

data Digit = Zero | One | Two 
type Digits = [Digit] 
data Sign = Pos | Neg -- Pos fuer Positive, Neg fuer Negative 
newtype Numeral = Num (Sign,Digits) 

instance Eq Sign where 
(==) Pos Pos = True 
(==) Neg Neg = True 
(==) _ _ = False 

instance Eq Digit where 
(==) Zero Zero = True 
(==) One One = True 
(==) Two Two = True 
(==) _ _ = False 

가 지금은 내가이 시도 내 사용자 정의 유형 숫자에 로그인을 체크 아웃 할 (==)

+0

어느'(==) (NUM (X, _)) (NUM (Y, _)) = X == y' 또는'민 (X, _) == 민 (y, _) = x == y'. – jpath

+0

또한 왜 'Numt'에'newtype'을 사용합니까? 왜'data Numeral = Num Sign Digits'가 아닌가? – jpath

+0

내가 작성한 첫 번째 사례를 입력 할 때 모호한 발생 = ''== ' 하지만 이전에는 여러 번 신고 된 것으로 나타 났으며 (두 번째 사례도 마찬가지 임) –

답변

3

대부분 이미 더 구체화 형태의 주석에 쓴 것을두고 :

이 코드에 몇 가지 문제가 있습니다

  1. 코드를 들여 쓰려면 instance 선언을 사용해야합니다. 그렇게하면 어떤 코드가 인스턴스 선언에 속하는지 컴파일러에게 알릴 수 있습니다.
  2. 다음 줄에서는 콘크리트 유형 (Eq Sign =>)에 유형 클래스 제약 조건을 묻습니다. 이것은 표준 Haskell에서는 불가능합니다. 컴파일러의 지시에 따라 FlexibleInstances 언어 확장을 사용하더라도 의미가 없습니다.

    instance (Eq Sign) => Eq (Numeral) where 
    

    유형 클래스 제약 조건은 유형 변수에만 사용됩니다. 예를 들어 :

    double :: Num a => a -> a 
    double x = x + x 
    

    는 여기에서 우리는 기능 doubleNum를 구현하는 모든 종류의 작동, 말한다. 반면에 double :: Num Int => Int -> IntIntNum 인스턴스가 있다는 것을 이미 알고 있으므로 중복됩니다. Eq Sign에 대해서도 동일합니다.

    예를 들어 인스턴스를 작성하는 유형에 다른 다형성 유형이 포함되어있는 경우 이러한 제약 조건은 의미가 있습니다. 여우보기 instance Ord a => Ord [a]. 여기서 우리는 목록 요소의 Ord 인스턴스를 사용하여 사전 적으로 목록을 나열합니다.

  3. 은 중위 또는 접두사 형식으로 정의 할 수 있지만 둘 다를 정의 할 수는 없습니다. 따라서 (==) (Num (x,_)) (Num (y,_)) = x == y 또는 Num (x,_) == Num (y,_) = x == y 중 하나입니다.

  4. 제품 유형을 만들기위한 새로운 타이핑 튜플은 다소 이상합니다. 더 복잡한 기본 유형에 대해 이미있는 기능을 사용하려면 새 유형이 보통 사용됩니다. 그러나 여기에 해당하지 않는 경우, 당신은 단지 DigitsSign의 정상적인 제품을 원할뿐입니다.

  5. 숫자의 Sign 만 비교하고 있습니다. 기술적으로 유효한 Eq 인스턴스이지만, 숫자의 자릿수를 비교하여 맨 앞자리 0을 잘랐을 수도 있습니다. 아래의 코드에서는 간단하게 유지하기 위해 0을 자르지 않았습니다.

data Digit = Zero | One | Two 
type Digits = [Digit] 
data Sign = Pos | Neg 
data Numeral = Num Sign Digits 

instance Eq Sign where 
    (==) Pos Pos = True 
    (==) Neg Neg = True 
    (==) _ _ = False 

instance Eq Digit where 
    (==) Zero Zero = True 
    (==) One One = True 
    (==) Two Two = True 
    (==) _ _ = False 

instance Eq Numeral where 
    Num s1 x1 == Num s2 x2 = s1 == s2 && x1 == x2 
+0

매우 잘 설명되어 있습니다. 예를 들어, Eq a => Eq customType이 사용되는 자습서에서 어딘가를 보았습니다. Signs를 현재 인스턴스와 비교하는 인스턴스를 포함하는 것으로 이해했습니다. 나는 단지 Signs를 비교했다는 것을 알고있다. 나는 Digit을 비교하기 위해 Num의 Eq의 또 다른 인스턴스를 만들고 싶었다. 나는 당신이 처음에 쓴 것을 시도했지만 일하지 않았다고 생각합니다. 이제 다시 시도하고 "모호한 발생 =="이라고 말했습니다. 어쨌든, 잘 설명했다. –

+0

죄송합니다 귀하의 코드를 복사하면 작동합니다. –

+0

@ 페가수스 고마워요. 인스턴스 선언에서 유형 제약 조건에 대해 2. 끝에 짧은 단락을 추가했습니다. – jpath

관련 문제