在sml中,为什么会产生错误:语法错误:删除IN IF

时间:2018-09-28 17:18:54

标签: emacs sml

我正在执行确定树是否平衡的功能。

fun balanced(tree) =
  let 
    fun size tree =
      case tree of
           Lf => 0
         | Br(xs,ys,zs) => 1 + size ys + size zs
    fun depth tree =
      case tree of
           Lf => 0
         | Br(xs,ys,zs) =>
            let val l_count = 1 + depth ys
                val r_count = 1+ depth zs
            in
              if l_count > r_count then l_count else r_count
            end
  in
    if size(ys) = size(zs) andalso depth(ys) = depth(zs) then true
    else if tree=Lf then true
    else false
  end;

但是会产生以下错误:

stdIn:829.18-829.20 Error: unbound variable or constructor: zs
stdIn:829.9-829.11 Error: unbound variable or constructor: ys
stdIn:829.48-829.50 Error: unbound variable or constructor: zs
stdIn:829.36-829.38 Error: unbound variable or constructor: ys

2 个答案:

答案 0 :(得分:2)

inend之间

  in
    if size(ys) = size(zs) andalso depth(ys) = depth(zs) then true
    else if tree=Lf then true
    else false
  end;

您使用从未定义的yszs。您在yszs函数中拥有的depthsize在这些函数中是本地的,而对balanced不可见。

答案 1 :(得分:1)

您尚未提供此函数所依据的数据类型。我认为它看起来像这样:

datatype 'a binary_tree = Lf | Br of 'a * 'a binary_tree * 'a binary_tree

由于代码,您会收到未绑定变量错误

if size(ys) = size(zs) andalso ...

在其范围内没有此类变量。这些变量仅在您的辅助函数范围内可用。这里有一些提示:

  1. xs实际上是位于分支和ys中的值时,不要命名变量zsxsyszs实际上是分支的左和右子树。更好的名称可以是x(如果不使用,则为_),leftright

  2. 使用Int.max (x, y)代替if x > y then x else y

    类似地,if foo then true else false等效于foo

    因此,balanced正文中不需要if-then-else。

  3. 直接在函数参数中执行模式匹配。

  4. 不必知道子树(size)中的元素数来确定它是否平衡。只需知道树的高度/深度(depth)。

  5. 将帮助器功能移出该功能。

    它们本身很有用。

    fun size Lf = 0
      | size (Br (_, left, right)) = 1 + size left + size right
    
    fun depth Lf = 0
      | depth (Br (_, left, right)) = 1 + Int.max (depth left, depth right)
    
  6. declarative way中写入balanced:空树(Lf)是微不足道的。如果左子树平衡,右子树平衡,并且左子树和右子树的深度之差不大于,则非空树(Br ...)被平衡。 1。

    fun balanced Lf = true
      | balanced (Br (_, left, right)) =
          balanced left andalso
          balanced right andalso
          ...the 'abs'(olute) difference of 'depth left' and 'depth right' is not more than 1...
    
  7. 此解决方案遍历了很多树:首先使用balanced,然后使用 使用depth。您可以通过返回一个元组(is_subtree_balanced, subtree_height)来编写仅遍历树一次的解决方案。

    fun balanced_helper Lf = (true, 0)
      | balanced_helper (Br (_, left, right)) =
        let val (is_left_balanced, left_height) = balanced_helper left
        in ...we can stop here if the left sub-tree isn't balanced...
           let val (is_right_balanced, right_height) = balanced_helper right
           in ...we can stop here if the right sub-tree isn't balanced...
              ...otherwise: (true, 1 + Int.max(left_height, right_height))...
           end
         end
    
    fun balanced tree = #1 (balanced_helper tree)