开始Haskell - 得到“不在范围内:数据构造函数”错误

时间:2010-08-28 19:56:15

标签: haskell scope

我正在查看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.

我希望Tree数据构造函数应该存在,因为我在height方法上面的行中定义了它。但是当我尝试加载文件时,我被告知数据构造函数不在范围内。感谢您对此错误发生原因的帮助和解释。谢谢, 凯文

3 个答案:

答案 0 :(得分:22)

更改

height (Tree node left right) 

height (Node node left right)

这意味着模式匹配适用于algebraic data type(ADT)的构造函数。 Tree不是构造函数,它是ADT的名称。

顺便说一句,你必须注释掉你的函数签名声明来编译代码,因为它包含一个错误。

然后,您可以通过

检查推断的类型
:t height

ghcihugs

答案 1 :(得分:5)

您的代码在多个级别上都是错误的。看起来你误解了代数数据类型。

  • 类型签名是错误的,Tree始终是特定类型的Tree - 您在其声明中称为a,可能是任何类型(因为您没有不要约束它。因此,heigth必须采用某种类型的Tree - Tree SomeType。您可以而且应该使用SomeType的最通用类型,即类似a的类型变量。
  • 在模式匹配时,您将特定构造函数命名为Node a (Tree a) (Tree a)Empty - 以匹配,而不是作为整体类型。因此height (Node ...)会匹配Nodeheight (Empty)会匹配Emptyheight (Tree ...)会尝试匹配名为Tree的构造函数,但是没有。这是你收到的错误信息。
  • 您永远不会比较(通过==)与构造函数。如果你写deriving (Show, Eq),它实际上会有效。但您应该使用模式匹配来确定您是否已达到Empty
  • 导致:您只匹配Node,而不是Empty - 您应该为Empty添加一个条款。
  • 此外,如果您修复了上述所有问题,您的函数仍会为所有输入返回0。你永远不会返回0或儿童'height的最大值 - 这反过来只会返回0或他们孩子的最大值height等无限期。你必须在每个级别增加结果;)

答案 2 :(得分:2)

您与构造函数进行模式匹配,即{{1>} ADT的个案Tree正是他们所有人的总和。

这样直截了当,,最重要的是,正确:

Tree