13

次のデータ型を のインスタンスにする必要がありますShow

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a 

私はこれにかなり慣れていませんが、まず、この宣言を次のように解釈しました

「ツリーと呼ばれる新しいタイプを作成しました。これは、タイプ a と b でパラメータ化されています。ツリーは、タイプ b のデータを保持するブランチと、さらに 2 つのツリー、または保持するリーフのいずれかになります。タイプaのデータ項目。」

今、私はそれをうまく「表示」する方法を作る必要があります (ネストされたブランチなど) deriving。これまでのところ、モジュール Main で関数を記述し、インタープリター ウィンドウでそれらを読み込んで再生するだけでした。そのため、コンストラクターなどで実際に行ったことはありません。それにもかかわらず、質問の冒頭に示されているように、ファイル内でツリーのデータ型を宣言することから始めて、そこから始めることができると考えました。

「表示」をいじってあまり成功しなかったので、ツリー全体を操作する前に、ツリーの小さなコンポーネントとそれを「表示」する方法を最初に定義する必要があるのではないかと考えました。

data Leaf a = Leaf a

instance Show (Leaf a) where
show (Leaf a) = ??? 

私は???で多くのことを試しました 「a」、a だけ、putStrLn などのスポットですが、次のようなことを言ったときに a の値を出力するものはありません

>show (Leaf 3)

実際、私は多くの場合これに遭遇しました。これはおそらく、物事を正しく見つけていないことを意味します。

Ambiguous occurrence `show'
    It could refer to either `Main.show', defined at a2.hs:125:1
                          or `Prelude.show',
                             imported from `Prelude' at a2.hs:2:8-11
                             (and originally defined in `GHC.Show')

...「Main.show」を呼び出して対処しましたが、もちろん機能しません。

問題は、これらすべてをどこに持ち込めばよいかということだと思います...あるいは単に、「リーフの「表示」ユーティリティを拡張する方法を理解できるようにするにはどうすればよいでしょうか?」(最初に定義する必要があると仮定します...)

4

4 に答える 4

22

次のように開始する必要があります。

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a

instance (Show a, Show b) => Show (Tree a b) where
    show (Leaf x) = show x
    show (Branch p l r) = ???

するためにはshow、まずs とsTree a bができる必要があります。インスタンスが機能するために必要な前提条件を指定します。show ab(Show a, Show b) =>

于 2012-09-21T19:43:37.520 に答える
7

最も簡単な答えは、Showインスタンスを自動的に派生させることです。

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a deriving Show

しかし、それでは希望する形式の出力が得られないとしましょう。独自のインスタンスを定義する場合は、次のShowようにします。

instance (Show a, Show b) => Show (Tree a b) where
    show (Leaf a) = "Leaf " ++ (show a)
    show (Branch b l r) = "Branch " ++ (show b) ++ " { " ++ l ++ ", " ++ r " }"

最初の行の読み方は、「given aand bare both instance of the Showtypeclass, Tree a bis also an instance of the Showtypeclass...」です。

ところで、インデントは重要です。貼り付けたスニペットで破損している可能性がありますが、宣言showの下の関数定義をインデントする必要があります。instance

于 2012-09-21T19:47:10.290 に答える
2

あなたのデータ型は の完璧な候補ですderiving Show

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a deriving Show

これにより、Show インスタンスが自動的に生成されます。

Show の手動インスタンスを作成する場合の思考プロセスは次のとおりです。

まず、基本的なスケルトン:

instance Show (Tree a b) where
   -- show :: Tree a b -> String
   show (Branch b ltree rtree) = {- some string -}
   show (Leaf a) = {- some string -}

aこれで、型の値を文字列として表示する何らかの方法が必要になることがわかりましたb。もちろん、それはshowそれらを直接呼び出すことができる必要があることを意味するのでa、 とbShow のインスタンスが必要です。その方法は次のとおりです。

instance (Show a, Show b) => Show (Tree a b) where
   -- show :: Tree a b -> String
   show (Branch b ltree rtree) = {- some string -}
   show (Leaf a) = {- some string -}

次に、次のような適切な文字列で空白を埋めるだけです。

instance (Show a, Show b) => Show (Tree a b) where
   -- show :: Tree a b -> String
   show (Branch b ltree rtree) = "(( " ++ show ltree ++ " ) <-- ( " ++ b ++ " ) --> ( " ++ show rtree ++ " ))"
   show (Leaf a) = "L " ++ show a
于 2012-09-21T19:42:28.323 に答える