2013-08-29 14 views
5

私は赤黒木で遊んでいます:私はGHCiの中で次の文を実行した場合Haskellの導出ショーインスタンス

-- 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です。私はこの問題に関する他のSOの投稿を読んできましたが、それらの解決策(例:Haskell: Deriving Show for custom type)は動作しません。例えば

、添加することにより、私は:lを使用してロードしようとする

instance Show Set where: 
    show (Set Char) = show Char 

Iは、次のエラーメッセージを表示します

: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. 

私がやろうとしていることにはいくつか問題があると思いますが、利用可能なドキュメントからそれを理解できないようです。

+0

'data tree a = ... deriving(Show)' – bheklilr

+0

'data RBT ... 'の最後に' deriving(Show) 'を追加すると、次のエラーメッセージが表示されます。色) データ型宣言の 'deriving'句から生成されたもの – Joe

+0

'data(Color)= R |の末尾に' deriving(Show) B ' – nponeccop

答えて

1

あなたは空の拡張機能を使用していないので、の組み込みderivingメカニズムを使用できるはずです。

データ型に対してShowインスタンスを自動的に派生させるには、型定義で使用されるすべての型もShowインスタンスである必要があります。 の末尾にderiving (Show)を追加してください。dataの定義をすべて追加してください。ほとんどの場合、構造的な等価性テストとタイプの表示可能性が求められるので、dataタイプにderiving (Eq, Show)を追加する習慣を覚えておくとよいでしょう。

また、あなただけのタイプため、タイプの別名のための任意の並べ替えのクラスのインスタンスを作成することはできません。キーワードtypeは、新しいエイリアスではなく、エイリアスを定義します。 RBT aタイプのShowインスタンスを作成した場合は、の別名にすぎないため、Set aはちょうどRBT aのエイリアスであるため、Set aとして宣言したものに自動的に使用されます。

4

あなたのインスタンスのコードが壊れている:

instance Show Set where 
    show (Set Char) = show Char 
  1. コンパイラはSetがデータコンストラクタではないと文句を言い、それはない - それは型シノニム名です。したがって、パターン内でSetを間違って使用しました。そこにデータコンストラクタを使用できます。RBTデータコンストラクタはTEです。

  2. あなたのインスタンス宣言は病気-kindedです:SetRBTRBTの同義語は、1型引数を持っている、それはそれは* -> *の種類署名で、タイプするタイプから、関数のです。しかし、Showインスタンスには、引数なしの型が必要です。型型であり、型コンストラクタではなく、* -> *の代わりに*という種類が必要です。したがって、instance Show (RBT Char)またはinstance (Show a) => RBT aのいずれかを指定して修正する必要があります。

おそらく、「その中に文字を表示することでcharのセットを表示する」と書いてください。だからあなたのインスタンスを修正する

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インスタンスを使用する方が簡単になります:あなたは仕事を成し遂げるためにRBTのコンストラクタにパターンマッチングを行う必要があります。

5

値を文字列に変換するために、Haskellはいわゆる型クラスを使用します。簡略化された型クラスは、引数の型によって異なる動作をする関数を提供するだけです。このアプローチは、オブジェクト指向プログラミング言語から知られているメソッドのオーバーロードに非常に似ています。タイプクラスShowは、あるタイプの値を文字列に変換するshowという関数を提供します。たとえば、式show 1は、文字列"1"を生成します。ある型の値を文字列に変換する関数showがある場合は、この型の型クラスShowのインスタンスが存在します。つまり、整数の型クラスShowのインスタンスがあります。

このshow関数は、ghciで式を評価するときにも使用されます。したがって、インスタンス(Show (Set Char))が存在しないこと、つまり、タイプSet Charの値を文字列に変換する方法がわかりません。 SetRBTColorなどのカスタムタイプの場合は、これらのタイプの値をコンソールに表示するには、タイプクラスShowのインスタンスを指定する必要があります。タイプColorのタイプクラスShowのインスタンスを定義するには、以下の定義を使用できます。

あなたはGHCiのに Rを書いた場合、それは Redを印刷します、です
instance Show Color where: 
    show R = "Red" 
    show B = "Black" 

。単純なHaskellデータ型の場合、型クラスShowの標準的な定義があります。たとえば、Colorの標準的な定義Showは次のとおりです。

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

はこのような定義のインスタンスからユーザーを軽減するために、Haskellは、いわゆる「導出メカニズム」を提供します。あなたは、データ型の定義の後

deriving (Show) 

を書く場合つまり、コンパイラは、あなたのデータ型のShow型クラスの正規のインスタンスを生成します。

データ型が別のデータ型を使用する場合、前者のShowインスタンスを派生させるには、後者のインスタンスShowが必要です。たとえば、次のデータ型を考えます。

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

データ型RBTはその定義タイプColorを使用します。 Tコンストラクタの標準Showインスタンスは "T"で始まり、その後はタイプColorの値を示します。したがって、RBTShowインスタンスを導出するには、Colorの場合はShowのインスタンスが必要です。

関連する問題