为什么会出现这些类型错误?
Why do I get these type errors?
我有一个数据类型:
data Tree = Empty | Node Int Tree Tree
我想要函数
nodeDepth :: Tree -> [(Int, Int)]
每个节点一对。第一个元素是标签(值),第二个是它的深度。
我的意图(原始代码)是这样的:
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)
但这不起作用。
怎么了?我正在使用 Frege 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.
这个:
zip nodeDepth' (Node label left right) [0]
zip
函数生成两个列表,但 nodeDepth'
和 (Node ...)
都不是列表。然后将结果(这是一个列表)应用到其他列表 [0]
,这解释了倒数第二条消息。我猜你是想写
zip (nodeDepth' (Node label left right)) [0]
但即使在这种情况下,nodeDepth' 也缺少一个参数来使括号中的表达式成为一个列表。
nodeDepth'
的第二个定义也无法编译,原因如下:
- 使用模式
[level]
匹配单元素列表,并调用单个元素 level
。美好的。但是您使用 level
作为 nodeDepth'(这是一个列表)的第二个参数,并在表达式 1+level
中将其用作数字。
在像
这样的表达式中
a : b : c
c
必须是列表(它不在您的示例中)并且 b
不能是列表,并且必须与 a
具有相同的类型。但是 nodeDepth' 应该是 return 一个列表。因此,整个 RHS 根本没有意义,因此你会得到这么多错误。
这里有个提示:既然你显然不希望 level 是一个列表,而且没有任何地方真正将列表传递给 nodeDepth',那么将模式 [level]
替换为 [=18 不是更好吗? =] ?
至于错误,例如考虑以下行:
nodeDepth (Node label left right) = zip nodeDepth' (Node label left right) [0]
由于Haskell 函数应用程序关联到左侧,zip 将函数 nodeDepth' 作为其第一个参数。要修复此特定错误,您可能需要编写:
zip (nodeDepth' (Node label left right)) [0]
但是你仍然缺少 nodeDepth' 的第二个参数,所以括号中的表达式只是 returns 一个函数而不是一个列表。
另一个错误是当您为非空树定义 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)]
如您所料。
我有一个数据类型:
data Tree = Empty | Node Int Tree Tree
我想要函数
nodeDepth :: Tree -> [(Int, Int)]
每个节点一对。第一个元素是标签(值),第二个是它的深度。
我的意图(原始代码)是这样的:
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)
但这不起作用。
怎么了?我正在使用 Frege 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.
这个:
zip nodeDepth' (Node label left right) [0]
zip
函数生成两个列表,但 nodeDepth'
和 (Node ...)
都不是列表。然后将结果(这是一个列表)应用到其他列表 [0]
,这解释了倒数第二条消息。我猜你是想写
zip (nodeDepth' (Node label left right)) [0]
但即使在这种情况下,nodeDepth' 也缺少一个参数来使括号中的表达式成为一个列表。
nodeDepth'
的第二个定义也无法编译,原因如下:
- 使用模式
[level]
匹配单元素列表,并调用单个元素level
。美好的。但是您使用level
作为 nodeDepth'(这是一个列表)的第二个参数,并在表达式1+level
中将其用作数字。 在像
这样的表达式中a : b : c
c
必须是列表(它不在您的示例中)并且 b
不能是列表,并且必须与 a
具有相同的类型。但是 nodeDepth' 应该是 return 一个列表。因此,整个 RHS 根本没有意义,因此你会得到这么多错误。
这里有个提示:既然你显然不希望 level 是一个列表,而且没有任何地方真正将列表传递给 nodeDepth',那么将模式 [level]
替换为 [=18 不是更好吗? =] ?
至于错误,例如考虑以下行:
nodeDepth (Node label left right) = zip nodeDepth' (Node label left right) [0]
由于Haskell 函数应用程序关联到左侧,zip 将函数 nodeDepth' 作为其第一个参数。要修复此特定错误,您可能需要编写:
zip (nodeDepth' (Node label left right)) [0]
但是你仍然缺少 nodeDepth' 的第二个参数,所以括号中的表达式只是 returns 一个函数而不是一个列表。
另一个错误是当您为非空树定义 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)]
如您所料。