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