Tree 为什么会出现这些类型错误?

Tree 为什么会出现这些类型错误?,tree,frege,Tree,Frege,我有一个数据类型: data Tree = Empty | Node Int Tree Tree 我想要函数 nodeDepth :: Tree -> [(Int, Int)] 每个节点一对。第一个元素是label(value),第二个元素是其深度 我的意图(原始代码)如下: nodeDepth (Node label left right) = zip nodeDepth' (Node label left right) [0] nodeDepth' Empty _ = [] no

我有一个数据类型:

data Tree = Empty | Node Int Tree Tree
我想要函数

nodeDepth :: Tree -> [(Int, Int)] 
每个节点一对。第一个元素是label(value),第二个元素是其深度

我的意图(原始代码)如下:

nodeDepth (Node label left right) = zip nodeDepth' (Node label left right) [0]
nodeDepth' Empty _ = []
nodeDepth' (Node label left right) [level] = label : nodeDepth' (Node label left right) level : (1 + level)
但这是行不通的

怎么了?我用的是弗雷格REPL

Error message are like :

E <console>.fr:22: t19906 occurs in type [t19906] rendering expression level{19727} untypable.

E <console>.fr:22: type error in  expression level
    type is   t19906
    used as   [t19906]

E <console>.fr:22: type error in  expression
    nodeDepth' (Node label left right) level:+ 1 level
    type is   [[t19909]]
    used as   [Int]


E <console>.fr:22: [[Int]] is not an instance of Num


E <console>.fr:20: type error in expression nodeDepth'
    type is apparently [t19961]
    used as function


H <console>.fr:20: too many or too few arguments perhaps?


E <console>.fr:20: type error in  expression Node label left right
    type is   Tree
    used as   [t19964]


E <console>.fr:20: type error in expression
    zip nodeDepth' (Node label left right)
    type is apparently [(t19961,t19964)]
    used as function


H <console>.fr:20: too many or too few arguments perhaps?


W <console>.fr:20: application of nodeDepth will diverge.
错误消息如下:
E.fr:22:t19906出现在类型[t19906]中,呈现表达式级别{19727}untyTable。
E.fr:22:表达式级别中的类型错误
型号是t19906
用作[t19906]
E.fr:22:表达式中的类型错误
节点深度“(节点标签左-右)级别:+1级别
类型为[[t19909]]
用作[Int]
E.fr:22:[[Int]]不是Num的实例
E.fr:20:表达式nodeDepth'中的类型错误
类型显然是[t19961]
用作函数
H.fr:20:争论可能太多或太少?
E.fr:20:表达式节点标签左-右中的类型错误
类型是树
用作[t19964]
E.fr:20:表达式中的类型错误
zip nodeDepth'(节点标签左-右)
类型显然是[(t19961,t19964)]
用作函数
H.fr:20:争论可能太多或太少?
W.fr:20:节点深度的应用将出现分歧。
这是:

zip nodeDepth' (Node label left right) [0]
zip
函数导出两个列表,但是
nodedeepth'
(节点…
都不是列表。然后将结果(这是一个列表)应用到另一个列表
[0]
,这解释了最后的第二条消息。我猜你是想写信

zip (nodeDepth' (Node label left right)) [0]
但即使在这种情况下,nodeDepth'也缺少一个参数,无法使括号中的表达式成为列表

由于以下原因,
nodededepth'
的第二个定义也不会编译:

  • 使用模式
    [level]
    匹配一个元素列表,并调用单个元素
    level
    。好的但是您使用
    level
    作为nodededepth'(这是一个列表)的第二个参数,并在表达式
    1+level
    中使用它作为数字
  • 以这样的表情

    a:b:c

c
必须是列表(您的示例中没有),而
b
不能是列表,并且必须具有与
a
相同的类型。但是nodeDepth'应该返回一个列表。因此,整个RHS毫无意义,因此会出现很多错误


这里有一个提示:既然您显然不希望level成为一个列表,而且没有任何地方真正将列表传递给nodeDepth',那么将模式
[level]
替换为
level
不是更好吗
nodeDepth (Node label left right) = zip nodeDepth' (Node label left right) [0]
由于Haskell functional application associates位于左侧,因此zip将函数nodeDepth'作为其第一个参数。要修复此特定错误,您可能需要编写:

zip (nodeDepth' (Node label left right)) [0]
但是您仍然缺少nodeDepth'的第二个参数,因此括号中的表达式只返回一个函数而不是一个列表

另一个错误是当您为非空树定义nodeDepth'时:模式匹配[level]将level捕获为单个元素,并在同一行上将其传递给自身。这只能通过假设level本身是一个列表来解决,但这也没有太大意义,因为在行的末尾,加法假设level是数字类型

nodeDepth' (Node label left right) [level] = label : nodeDepth' (Node label left right) level : (1 + level)
下面的函数nodeDepth使用深度优先搜索遍历树,并构建标签列表和各个节点的深度

data Tree = Empty | Node Int Tree Tree

wikiTree = Node 2 (Node 7 (Node 2 Empty Empty) (Node 6 (Node 5 Empty Empty) (Node 11 Empty Empty))) (Node 5 Empty (Node 9 (Node 4 Empty Empty) Empty))

nodeDepth :: Tree -> [(Int, Int)]
nodeDepth Empty = []
nodeDepth (Node label left right) = nodeDepthAccumulator (Node label left right) 0

nodeDepthAccumulator :: Tree -> Int -> [(Int, Int)]
nodeDepthAccumulator Empty _ = []
nodeDepthAccumulator (Node label left right) depth = (label,depth) : nodeDepthAccumulator left (depth+1) ++ nodeDepthAccumulator right (depth+1)

在获得的示例wikiTree上执行nodeDepth:

> nodeDepth wikiTree
> [(2, 0),(7, 1),(2, 2),(6, 2),(5, 3),(11, 3),(5, 1),(9, 2),(4, 3)]

正如你所料。

Frege;我认为使用标记而不是更合适。你无法获得节点的深度。你只能得到它的高度(例如,距离树叶最远的距离),那么你想得到什么呢?@Zeta谢谢你的编辑。如果他使用ghci,类型错误将是同构的。但没关系,我们关心这件事。:)@泽塔:我认为添加哈斯克尔标签是值得的,因为这个问题中出现的问题对哈斯克尔来说也是一样的,而弗雷格标签“限制”了这个问题的公开性。