2013-08-29 1 views
5

내가 레드 - 블랙 트리와 함께 연주하고있다 : 나는 GHCi에서 다음 문을 실행하면하스켈 유도 표시 인스턴스

-- Taken from Okasaki 1999 
module RedBlackTree where 

--node coloring data 
--a node is R (red) or B (black) 
data Color = R | B 

--tree constructor 
--a RBT can be E (empty) or be T (a non empty tree) 
data RBT e = E | T Color (RBT e) e (RBT e) 

--set operations on tree 
type Set a = RBT a 

--define an empty set 
empty :: Set e 
empty = E 

--define a member of a set 
--Sees if an item of type e is 
--in a set if type e elements 
member :: (Ord e) => e -> Set e -> Bool 
member x E = False 
member x (T _ a y b) | x < y = member x a -- if less, go left 
        | x == y = True 
        | x > y = member x b -- if more, go right 


--tree operations 
--Insert an element 
insert :: (Ord e) => e -> Set e -> Set e 
insert x s = makeBlack (ins s) 
    where ins E = T R E x E --basically the typical BST insert 
      ins (T color a y b) | x < y = balance color (ins a) y b 
           | x == y = T color a y b 
           | x > y = balance color a y (ins b) 
      makeBlack (T _ a y b) = T B a y b --inserts a black node 

-- balance operations 
--case 1: 
balance B (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d) 
--case 2: 
balance B (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d) 
--case 3: 
balance B a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d) 
--case 4: 
balance B a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d) 
--generic balancing operation 
balance color a x b = T color a x b 

가 :

> RedBlackTree.insert ('b') (RedBlackTree.T R E ('a') E) 

다음과 같은 오류 메시지가 저를 알려주는이 없다 Set Char에 대한 쇼의 예 :

<interactive>:116:1: 
No instance for (Show (Set Char)) arising from a use of `print' 
Possible fix: add an instance declaration for (Show (Set Char)) 
In a stmt of an interactive GHCi command: print it 

나는 나무가를 호출하기 때문에 작업을 알고여기서 ...은 이전에 실행 된 명령문이고, 반환 값은 True입니다. 이 문제에 대한 다른 게시물을 읽었지 만 찾을 수있는 솔루션 (예 : Haskell: Deriving Show for custom type)이 작동하지 않습니다. 예를 들어, 추가하여

:

나는 다음과 같은 오류 메시지가
instance Show Set where: 
    show (Set Char) = show Char 

내가하려고 할 때이 :l를 사용하여로드하려면

: L 빨강 - 검정 - tree.hs 을 [1 1] 컴파일 RedBlackTree (해석 레드 - 블랙 - tree.hs)

red-black-tree.hs:54:11: Not in scope: data constructor `Set' 

red-black-tree.hs:54:15: Not in scope: data constructor `Char' 

red-black-tree.hs:54:28: Not in scope: data constructor `Char' 
Failed, modules loaded: none. 
,536,

내가 뭘하려고하는지에 관해서 몇 가지 문제가 있다고 생각하지만 사용 가능한 문서에서 그것을 파악할 수없는 것처럼 보입니다.

+0

'data tree a = ... deriving (Show) '을 사용하십시오. – bheklilr

+0

'data RBT ...'의 끝에'deriving (Show) '을 추가하면 다음과 같은 오류 메시지가 나타납니다. Color) 데이터 형식 선언의 'deriving'절에서 발생합니다. – Joe

+0

'data (Color) = R | B' – nponeccop

답변

1

환상적인 확장 프로그램이 없으므로 에 기본 제공 deriving 메커니즘을 사용할 수 있어야합니다.

데이터 형식에 대해 Show 인스턴스를 자동으로 파생 시키려면 형식 정의에 사용 된 모든 형식의 인스턴스도 Show이어야합니다. 끝 부분에 deriving (Show)을 모두 입력하십시오. data 정의를 추가하십시오. 거의 모든 유형에 대해 구조적 평등성 테스트 및 표시 가능성을 원할 것이므로 유형에 deriving (Eq, Show)을 추가하는 습관을 들여야 할 수 있습니다.

또한, 당신은 유형 별칭에 대한 어떤 종류의 클래스 인스턴스를 만들 수 없습니다 만 유형합니다. 키워드 type은 새 유형이 아닌 유형 별명을 정의합니다. RBT a 유형에 Show 인스턴스를 만들면 Set aRBT a의 별칭 일 뿐이므로 Set a으로 선언 한 항목에 자동으로 사용됩니다.

4

인스턴스 코드 분류됩니다

instance Show Set where 
    show (Set Char) = show Char 
  1. 컴파일러는 Set는 데이터 생성자 아니라고 불평, 그것은하지 않습니다 -이 유형의 동의어 이름입니다. 따라서 패턴에서 Set을 잘못 사용했습니다. 데이터 생성자를 사용할 수 있으며 RBT 데이터 생성자의 경우 TE입니다.

  2. 인스턴스 선언은 잘못 kinded입니다 : SetRBT의 동의어이며 RBT 하나 개의 형식 인수를 가지고, 그게 * -> * 일종의 서명으로, 입력 유형에서 함수의입니다. 그러나 Show 인스턴스에는 인수가없는 유형이 필요합니다. 유형이 아니고 유형 생성자가 아니며 유형 대신 *을 입력해야합니다. 따라서 instance Show (RBT Char) 또는 instance (Show a) => RBT a을 제공하여 문제를 해결해야합니다.

"내부에 문자를 표시하여 일련의 문자 표시"를 작성하는 것이 좋습니다.

instance Show (RBT Char) where 
    show a = "something" 

을하지만 유용한 아무것도 표시되지 않습니다

그래서 인스턴스를 해결합니다. 당신은 작업을 완수하기 위해 통화 연결음의 생성자에 패턴 매칭을 수행해야합니다

instance Show (RBT Char) where 
    show E = "something" 
    show (T a b c d) = "something else" 

하지만 당신의 작업은 간단합니다 단지 RBT aColor의 파생 Show 인스턴스를 사용 할 수 있습니다.

5

값을 문자열로 변환하기 위해 Haskell은 소위 유형 클래스를 사용합니다. 단순화 된 유형 클래스는 인수의 유형에 따라 다르게 동작하는 함수를 제공하기 만합니다. 이 접근법은 객체 지향 프로그래밍 언어에서 알려진 메소드 오버로딩과 매우 유사합니다. 유형 클래스 Show은 어떤 유형의 값을 문자열로 변환하는 show이라는 함수를 제공합니다. 예를 들어, 표현 show 1은 문자열 "1"을 생성합니다. 어떤 유형의 값을 문자열로 변환하는 함수 show이있는 경우이 유형에 대해 Show 유형의 인스턴스가 있다고합니다. 즉, 정수에는 유형 클래스 Show의 인스턴스가 있습니다.

show 기능은 ghci에서 표현식을 평가할 때도 사용됩니다. 따라서 인스턴스 (Show (Set Char))이 없다는 것을 알게됩니다. 즉, Set Char 유형의 값을 문자열로 변환하는 방법을 알지 못합니다. Set, RBTColor과 같은 사용자 정의 유형의 경우 콘솔에 이러한 유형의 값을 표시하려면 유형 클래스 Show의 인스턴스를 제공해야합니다. Color 유형의 클래스 Show의 인스턴스를 정의하려면 다음 정의를 사용할 수 있습니다. 당신이 ghci에 R를 작성하는 경우

instance Show Color where: 
    show R = "Red" 
    show B = "Black" 

즉, 그것은 Red를 인쇄합니다. 간단한 Haskell 데이터 타입의 경우, Show 타입 클래스에 대한 표준적인 정의가있다. 예를 들어 Color에 대한 Show의 표준 정의는 다음과 같습니다.

instance Show Color where: 
    show R = "R" 
    show B = "B" 

하스켈은 사용자가 이처럼 인스턴스를 정의하지 못하게하기 위해 소위 "파생 메커니즘"을 제공합니다. 당신이 데이터 유형의 정의 후

deriving (Show) 

를 작성하는 경우 즉, 컴파일러는 데이터 유형에 대한 Show 형 클래스의 정규 인스턴스를 생성합니다.

데이터 형식이 다른 데이터 형식을 사용하는 경우 앞의 Show 인스턴스의 파생에는 Show 인스턴스가 필요합니다. 예를 들어, 다음 데이터 유형을 고려하십시오.

data RBT e = E | T Color (RBT e) e (RBT e) 

데이터 유형 RBT는 정의 타입 Color을 이용한다. 표준 ShowT 생성자의 인스턴스는 "T"로 시작하고 이후 Color 유형의 값을 표시합니다. 따라서 RBT에 대한 Show 인스턴스를 유도하려면 Color에 대해 Show의 인스턴스가 필요합니다.