web-dev-qa-db-ja.com

Haskellの開始-「スコープ外:データコンストラクター」エラーが発生する

Haskell O'Reillyの本の問題を取り上げます。私が取り組んでいる問題は

Using the binary tree type that we defined earlier in this chapter, 
write a function that will determine the height of the tree. The height 
is the largest number of Hops from the root to an Empty. For example, the 
tree Empty has height zero; Node "x" Empty Empty has height one; 
Node "x" Empty (Node "y" Empty Empty) has height two; and so on.

私はコードをch3.hsというファイルに書き込んでいます。これが私のコードです:

36 data Tree a = Node a (Tree a) (Tree a)
37             | Empty
38               deriving (Show)
39
40 --problem 9:Determine the height of a tree
41 height :: Tree -> Int
42 height (Tree node left right) = if (left == Empty && right == Empty) then 0 else max (height left) (height right) 

ターミナルでghciを開き、:load ch3.hsと入力します。これを行うと、次のエラーが発生します。

Prelude> :load ch3.hs
[1 of 1] Compiling Main             ( ch3.hs, interpreted )

ch3.hs:42:7: Not in scope: data constructor `Tree'
Failed, modules loaded: none.

高さメソッドの上の行で定義したため、ツリーデータコンストラクターがそこにあるはずです。しかし、ファイルをロードしようとすると、データコンストラクターがスコープ内にないというメッセージが表示されます。このエラーが発生する理由の説明と説明に感謝します。おかげで、ケビン

20
Kevin Burke

変化する

height (Tree node left right) 

height (Node node left right)

つまり、パターンマッチングは 代数的データ型 (ADT)のコンストラクターで機能します。 Treeはコンストラクタではなく、ADTの名前です。

ところで、エラーが含まれているため、コードをコンパイルするには関数のシグネチャ宣言をコメント化する必要があります。

次に、推論された型を次の方法で確認できます

:t高さ

ghci または hugs

22
maxschlepzig

あなたのコードはいくつかのレベルで間違っています。代数的データ型を誤解しているようです。

  • 型シグネチャが間違っています。Treeは常に特定の型のTreeです。これは宣言でaを呼び出したものであり、どの型でもかまいません(制約しません)。したがって、heigthは、何らかのタイプのTreeを取得する必要があります-_Tree SomeType_も必要です。 SomeTypeには最も一般的な型、つまりaのような型変数を使用できます。
  • パターンマッチングを行う場合は、型全体ではなく、特定のコンストラクターNode a (Tree a) (Tree a)またはEmptyを照合対象として指定します。したがって、height (Node ...)Nodeと一致し、height (Empty)Emptyと一致し、height (Tree ...)Tree、しかしありません。それはあなたが受け取るエラーメッセージです。
  • コンストラクタでcompare(_==_を介して)することは決してありません。 deriving (Show, Eq)と書けば実際に機能します。ただし、パターンマッチングを使用して、Emptyに達したかどうかを判断する必要があります。
  • その結果、NodeではなくEmptyのみが一致します-Emptyの句を追加する必要があります。
  • また、上記の問題をすべて修正した場合、関数はすべての入力に対して0を返します。 0または子のheightの最大値以外を返すことはありません。これにより、子のheightの0または最大値のみが無限に返されます。各レベルで結果をインクリメントする必要があります;)
5
user395760

Tree ADTのconstructors、つまりcasesに対してパターンマッチします。 Treeは、それらすべてを合計したものです。

次のようにはるかに簡単ですand何よりも正しい:

height Empty = 0
height (Node _ l r) = 1 + max (height l) (height r)
2
Dario