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

ブライアンが指摘するように、SMLではとを使用andalsoします。orelse

ただし、これが正しく修正されていれば、コードにエラーはありません。

アンドレアス・ロスバーグが指摘したように、あなたがフォームの表現を書くときはいつでも

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

ところで、サブツリーの重みが何度も何度も計算されるため、これは移動体のバランスが取れているかどうかを判断するための非常に非効率的な方法です。モバイルのバランスが取れていない場合は NONE を返し、バランスが取れている場合は SOME w を返す関数 weight_of_balanced_mobile を考えてみてください。

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;

ここでの問題は、「バランスの取れた」関数が 1 ビットの情報しか返さないことですが、効率的に計算するには、より多くの情報が必要です。私はブーリアンを危険信号と見なすようになりました。

計算を構造化してより多くの情報 (バランスが取れているかどうかだけでなく、どれだけ重いか)を取得するもう 1 つの方法は、継続を渡すことです。モバイルと「このモバイルのバランスがとれている場合にどうするか」引数を取る関数を作成します。ああ、そうでない場合に使用する '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

に変更andするandalsoと、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ため、 のブール制約を満たさないためです。andalsoint

于 2013-01-16T19:03:47.400 に答える