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

Emacs 在sml中,为什么会产生错误:语法错误:在IF中删除,emacs,sml,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) =>

我在做一个函数来确定一棵树是否平衡

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错误:未绑定变量或构造函数:zs
stdIn:829.9-829.11错误:未绑定变量或构造函数:ys
stdIn:829.48-829.50错误:未绑定变量或构造函数:zs
stdIn:829.36-829.38错误:未绑定变量或构造函数:ys

介于
中的
结束之间

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

您使用了以前从未定义过的
ys
zs
。您在
depth
size
中拥有的
ys
zs
函数是这些函数的本地函数,对于
balanced

不可见。您没有提供此函数操作的数据类型。我想是这样的:

datatype 'a binary_tree = Lf | Br of 'a * 'a binary_tree * 'a binary_tree
由于代码

if size(ys) = size(zs) andalso ...
在其范围内没有此类变量。这些变量仅在助手函数的作用域中可用。以下是一些提示:

  • xs
    实际上是驻留在分支中的值,
    ys
    zs
    实际上是分支的左、右子树时,不要命名变量
    xs
    ys
    。更好的名称可以是
    x
    (或者
    \u
    ,如果您不使用它),

  • 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)
    
  • 使用
    Int.max(x,y)
    而不是
    如果x>y,则使用x else y

    类似地,
    如果foo那么true或者false
    相当于只
    foo

    因此,您不需要在
    主体中使用if-then-else来平衡

  • 直接在函数参数中执行模式匹配

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

  • 将辅助函数移出此函数

    它们本身就很有用

    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)
    
  • 在a中写入
    balanced
    :空树(
    Lf
    )是微不足道的平衡。如果左子树是平衡的,右子树是平衡的,并且左、右子树的深度差不大于1,则非空树(
    Br…
    )是平衡的

    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...
    
  • 此解决方案遍历树的次数相当多:首先使用
    balanced
    ,然后使用
    depth
    。您可以为此练习编写一个只遍历树一次的解决方案,方法是返回元组
    (子树是否平衡,子树高度)


  • 欢迎来到StackOverflow!我已经删除了
    emacs
    标记,并重新格式化了您的代码,以便它在StackOverflow的降价中正确突出显示。我对代码的缩进做了一些小的调整,使其更具可读性。您可能希望在主函数中使用
    树上的模式匹配(如
    大小
    深度
    ),那么如何使“可见”@이이도경 在
    中的
    之间声明它,或者在
    中的
    结束之间有一个
    案例树。请参阅
    melpomene
    的评论。感谢您的帮助,那么如何直接在函数参数中执行模式匹配(回复中的数字3)?我对sml不是很熟悉:(我不能理解7的其他部分是什么?我也可以跟进这个过程…我已经展示了如何在不使用三个位置的情况下进行模式匹配。在你先用简单的方法解决问题之前,不要担心bullet(7)。