0

我对 SML 很陌生。我目前正在做一个检查手机是否平衡的项目。

我的数据类型 mobile 定义如下:

datatype mobile = Object of int 
                | Wire   of mobile * mobile

然后我有一个权重函数来检查手机的重量:

fun weight (Object w)   = w 
  | weight (Wire (l,r)) = weight l + weight r

我现在正在尝试检查手机是否平衡。我有以下内容:

fun balanced (Object w)   = true 
  | balanced (Wire (l,r)) = if weight l = weight r and balanced l and balanced r then true else false

但是,我不断收到错误消息:

stdIn:18.19-18.31 Error: syntax error: deleting  AND ID
stdIn:18.34 Error: syntax error found at AND

有人可以告诉我我做错了什么吗?

4

3 回答 3

3

正如 Brian 指出的那样,我们在 SML 中使用andalso和。orelse

但是,当正确修复时,代码中没有错误。

同样正如 Andreas Rossberg 所指出的,当你写下表格的表达式时

if b then 
  true
else
  false

那你应该马上想到这张图片,并用表情来交换b,因为它显然是一样的。

鉴于此,您的balanced函数最终看起来像这样

fun balanced (Object w)   = true
  | balanced (Wire (l,r)) = weight l = weight r andalso
                            balanced l andalso balanced r
于 2013-01-17T00:16:34.480 回答
2

顺便说一句,这是确定移动设备是否平衡的一种非常低效的方法,因为子树的权重是一遍又一遍地计算的。考虑一个函数 weight_of_balanced_mobile,如果移动设备不平衡,则返回 NONE,如果平衡,则返回 SOME w。

fun weight_of_balanced_mobile (Object w) = SOME w
  | weight_of_balanced_mobile (Wire (l,r)) =
       case weight_of_balanced_mobile l
         of NONE => NONE
          | SOME u => case weight_of_balanced_mobile r
                        of NONE => NONE
                         | SOME v => if u = v then SOME (u+v) else NONE;

 fun is_balanced mobile =
        case weight_of_balanced_mobile mobile
          of NONE => false
           | SOME _ => true;

这里的问题是你的“平衡”函数只返回一点信息,而为了有效地计算,我们需要更多信息。我开始将布尔值视为危险信号。

另一种构建计算结构以便获得更多信息的方法(不仅仅是平衡的东西,而是的重量)是传递一个延续。我们将创建一个函数,它接受一个移动设备和一个“如果这个移动设备是平衡的怎么办”参数。哦,如果它不是那么好,让我们让它使用一个 'value 值。

(* val check_balance : mobile -> 'a -> (int -> 'a) -> 'a *)
fun check_balance (Object w) _ f = f w
  | check_balance (Wire (l,r)) d f =
       check_balance l d (fn u =>
          check_balance r d (fn v =>
             if u = v then f (u+v) else d));

fun is_balanced mobile = check_balance mobile false (fn _ => true);

如果你看的恰到好处,这和之前的代码倒过来是一样的。

于 2013-06-22T10:36:39.127 回答
1

更改andandalso可以克服syntax error found at AND错误。

- fun balanced (Object w) =
    true | balanced(Wire(l,r)) = 
    if weight l = weight r andalso balanced l andalso r
    then
     true
    else
     false;

但是你会得到这个:

stdIn:5.8-5.29 Error: operand of andalso is not of type bool [tycon mismatch]
  operand: mobile
  in expression:
    (balanced l) andalso r

这是因为weight函数的类型val weight = fn : mobile -> int不满足布尔约束,andalso因为它返回一个int.

于 2013-01-16T19:03:47.400 回答