Recursion 从SML中的树创建列表时出现语法错误
我有以下两种数据类型:Recursion 从SML中的树创建列表时出现语法错误,recursion,tree,sml,Recursion,Tree,Sml,我有以下两种数据类型: datatype leaf = Slist of string list | Real of real | nil; datatype 'a tree = Empty | Node of leaf * 'a tree * 'a tree * 'a tree; 下面的代码将遍历所有长度为1/2的树,并形成叶子中的值列表 fun list12(Empty:'a tree) = nil | list12(Node(leaf leaf1, 'a tree a1, 'a t
datatype leaf = Slist of string list | Real of real | nil;
datatype 'a tree = Empty | Node of leaf * 'a tree * 'a tree * 'a tree;
下面的代码将遍历所有长度为1/2的树,并形成叶子中的值列表
fun list12(Empty:'a tree) = nil
| list12(Node(leaf leaf1, 'a tree a1, 'a tree a2, 'a tree a3)) =
if (not(a1 = Empty) andalso not(a2 = Empty) andalso not(a3 = Empty))
then list12(a1)::list12(a2)::list12(a3)
else leaf1::list12(a1)::list12(a2)::list12(a3);
问题是,我遇到语法错误,例如
stdIn:94.59-94.66 Error: syntax error: deleting TYVAR ID
stdIn:94.71-94.78 Error: syntax error: deleting TYVAR ID
stdIn:94.83-94.93 Error: syntax error: deleting TYVAR ID ID
stdIn:94.93-94.97 Error: syntax error: deleting RPAREN RPAREN EQUALOP
stdIn:94.98-94.102 Error: syntax error: deleting IF LPAREN
stdIn:94.109-94.116 Error: syntax error: deleting EQUALOP ID
代码本身并不复杂。基本大小写是,如果为空,则返回null。 如果它没有三个节点,那么我添加叶的值并递归调用节点上的函数。如果是这样,我只是递归地调用节点上的函数,而不添加叶 它之所以有效是因为它是空的,它通过将nil添加到列表中来结束搜索,而这没有任何作用 我还尝试了其他情况,例如使用
和而不是和,以及其他版本的代码,例如
| list12(Node(leaf1, Empty, Empty, Empty)) = nil
| list12(Node(leaf2, a1, Empty, Empty)) = leaf2::list12(a1);
| list12(Node(leaf3, b1, b2, Empty)) = leaf3::list12(b1)::list12(b2);
| list12(Node(leaf4, c1, c2, c3)) = list12(c1)::list12(c2)::list12(c3);
但我发现,上述情况并不适用于所有情况
你知道为什么会出现语法错误吗
旁注,为什么1.0=2.0
不起作用,但在摘要中它说它适用于reals?它似乎只适用于整数和
,语法错误:
您不能重新绑定nil
。它是内置列表类型的保留关键字(即nil
=[]
)
您不需要为类型加前缀,例如树t1
。您可以推断类型(不指定类型并让类型检查器猜测),也可以使用正确的语法(t1:'a tree
)对其进行注释
假设我们排除了语法错误,通过删除类型注释和添加一些格式,更多地依赖于推理,那么您的代码可能是这样的:
datatype leaf = Slist of string list | Real of real | Nil;
datatype 'a tree = Empty | Node of leaf * 'a tree * 'a tree * 'a tree;
fun list12 Empty = []
| list12 (Node(leaf1, a1, a2, a3)) =
if (not(a1 = Empty) andalso not(a2 = Empty) andalso not(a3 = Empty))
then list12(a1)::list12(a2)::list12(a3)
else leaf1::list12(a1)::list12(a2)::list12(a3);
类型错误:
查看op::::“a*”a list->“a list
,以及您对list12(a1)::list12(a2)
的使用,类型检查器必须找到一些'a
,以便'a='a list
。这就像找到一个x
,这样x=x+1
。显然,无论list12
返回什么,两边都有相同的东西
一个肮脏而低效的技巧是使用@
操作符(append)。一种更简洁的方法是在树上折叠,折叠时使用的功能可以访问整个节点(如:
您可以将其折叠为一个函数-这种方法是将遍历逻辑分离为para
,将累加逻辑分离为list12
的辅助函数
比较real
s
为什么1.0=2.0不起作用,但在总结中它说它适用于reals
我不知道你指的是什么摘要。此问题的答案如下:(此答案最初放在此处,但由于它是一个单独的问题,因此被移到了此处。)语法错误:
您不能重新绑定nil
。它是内置列表类型的保留关键字(即nil
=[]
)
您不需要为类型加前缀,例如树t1
。您可以推断类型(不指定类型并让类型检查器猜测),也可以使用正确的语法(t1:'a tree
)对其进行注释
假设我们排除了语法错误,通过删除类型注释和添加一些格式,更多地依赖于推理,那么您的代码可能是这样的:
datatype leaf = Slist of string list | Real of real | Nil;
datatype 'a tree = Empty | Node of leaf * 'a tree * 'a tree * 'a tree;
fun list12 Empty = []
| list12 (Node(leaf1, a1, a2, a3)) =
if (not(a1 = Empty) andalso not(a2 = Empty) andalso not(a3 = Empty))
then list12(a1)::list12(a2)::list12(a3)
else leaf1::list12(a1)::list12(a2)::list12(a3);
类型错误:
查看op::::“a*”a list->“a list
,以及您对list12(a1)::list12(a2)
的使用,类型检查器必须找到一些'a
,以便'a='a list
。这就像找到一个x
,这样x=x+1
。显然,无论list12
返回什么,两边都有相同的东西
一个肮脏而低效的技巧是使用@
操作符(append)。一种更简洁的方法是在树上折叠,折叠时使用的功能可以访问整个节点(如:
您可以将其折叠为一个函数-这种方法是将遍历逻辑分离为para
,将累加逻辑分离为list12
的辅助函数
比较real
s
为什么1.0=2.0不起作用,但在总结中它说它适用于reals
我不知道你指的是什么摘要。这个问题在这里得到了回答:(这个答案最初放在这里,但由于它是一个单独的问题,所以被移到了那里。)
fun para f e Empty = e
| para f e0 (t0 as Node (x, t1, t2, t3)) =
let val e1 = f (e0, t0)
val e2 = para f e1 t1
val e3 = para f e2 t2
val e4 = para f e3 t3
in e4 end
fun isNode (Node _) = true
| isNode Empty = false
fun list12 t =
let fun extract (xs, Empty) = xs
| extract (xs, Node (x, t1, t2, t3)) =
if isNode t1 andalso isNode t2 andalso isNode t3
then x::xs
else xs
in para extract [] t end