List 构造函数不在范围/模式匹配分析错误中

List 构造函数不在范围/模式匹配分析错误中,list,haskell,tree,List,Haskell,Tree,我有以下数据类型: data Tree a = Node [Tree a] 我想计算这样一棵树中有多少个节点,因此我定义了以下内容: count:: Tree a -> Integer count [] = 0 count Node label [childrenTree a] = 1 + count a 这给了我一个错误,说“parseerrorinpattern:true”。如果我将childrentreea更改为treea,则表示数据构造函数不在范围内 如何解决此问题?这指定函数

我有以下数据类型:

data Tree a = Node [Tree a]
我想计算这样一棵树中有多少个节点,因此我定义了以下内容:

count:: Tree a -> Integer
count [] = 0
count Node label [childrenTree a] = 1 + count a
这给了我一个错误,说“parseerrorinpattern:true”。如果我将
childrentreea
更改为
treea
,则表示数据构造函数不在范围内


如何解决此问题?

这指定函数
count
有三个参数,这不是您想要的:

count Node label [childrenTree a] = ...
   -- ^1   ^2    ^3
此外

count [] = ...
指定只有一个参数,该参数必须是列表(确切地说是空列表)。您希望
count
将树作为参数,而不是列表

编写代码的正确方法是:

count:: Tree a -> Integer
count (Node subtrees) = ...   -- here, we have subtrees :: [Tree a]
或者:

count:: Tree a -> Integer
count (Node [])     = ...
count (Node (t:ts)) = ...
           --here t is the first tree in the list, ts is the list of remaining ones

下面是一个完整的工作程序:

data Tree a = Node [Tree a]

count:: Tree a -> Integer
count (Node [])     = 1
count (Node (t:ts)) = count t + count (Node ts)

-- a little test
main :: IO ()
main = print (count (Node [Node [], Node [Node[], Node[]]]))

输出是
5
,这是输入中
节点的数目。

一般树中有一个棘手的部分需要考虑,树本身有函数,树列表上有递归。 另一件事是,您的树不会保存任何有价值的信息,您可以将其稍作更改:

data Tree a = Node a [Tree a] deriving (Show)
这两个功能类似于:

count:: Tree a -> Integer
count (Node _ trees) = 1 + countLs trees

countLs []     = 0
countLs (t:ts) = (count t) + (countLs ts)
还有一个小演示:

genTree1 = NodeG "1" [NodeG "2" [],
                         NodeG "3" [NodeG "4" [],
                                   NodeG "5" [NodeG "6" [],
                                             NodeG "7" [],
                                             NodeG "8" []
                                             ]
                                   ]
                         ]
运行示例:


为什么我不想要三个论点
count[]=..
应该是递归的基本情况,因此当我们在树的底部时,它将停止。我如何实现这一点?“为什么我不需要三个参数?”因为
count
接受单个
树a
并返回一个整数。正如您的类型签名所示,这只是一个参数。我希望您只是忘记了,或者没有意识到您需要括号,以及预期的
计数(节点标签[childrenTree a])
,这是一个单树参数。(虽然表面上看起来是一个树类型,它有数据连接到节点,而你的树类型没有。这本身是不寻常的-类型定义中的
a
实际上没有被使用。)@RobinZigmond确实如此,
[childrenTree a]
无论如何都不是一个有效的模式。@AdityaSubramanian,一旦有多个子树,它就会失败,由于
[childrenTrees]
只与长度为1的列表匹配。因此,这种方法在某种程度上不会遇到我之前遇到的类型匹配错误,因此我不太确定您是如何解决这一问题的。对于一棵树的高度,你会怎么做?我当前的实现试图模仿你的实现,但我没能做到:
height::treea->Integer height(Node(x:xs))=1+最大高度(x:xs)height(x:xs)=贴图高度(x:xs)
我希望“高度”将映射整个列表的高度,最大值将返回此列表的最大值,但有些地方似乎出了问题。@AdityaSubramanian这是一个完全不同的问题,您应该将其作为新问题添加。现在,如果这两个答案中的一些对你的答案有效,接受其中一个,然后继续问一个新问题,因为如果我们把所有的问题都混合在一个问题中,那么更多的读者就不会理解了
$> count genTree1
8