6

2 つの数値を比較する一致パターンについて助けが必要です。そんな感じ:

let test x y =
   match x with
   | y when x < y -> printfn "less than"
   | y when x > y -> printfn "greater than"
   | _ -> printfn "equal"

どういうわけか、x が 0 で y が 200 の場合、「_」のケースになります。ここで何が間違っていますか?

4

6 に答える 6

17

あなたのコードの問題は、あなたが書くときです:

match x with 
| y when x < y -> (...)

.. これは、 (in ) の値を (in ) という名前の新しい変数に代入し、この新しい (現在は の値を含む) を - の値と比較することを意味するxため<expr>match <expr> withこれyは常にを返します。バインドされた変数の名前はいつでも変更できるため、コードは次のように記述した場合と同じになります。<pat>| <pat> when ...yxxfalse

match x with 
| newY when x < newY -> (...)

これで、これが一致しない理由がわかりましたx。それ自体と比較しているだけだからです。

パターン マッチングは、タプルや判別共用体、リスト、配列、オプション型など、より複雑な構造の入力がある場合に特に便利です。しかし、単純に数値を比較したい場合は、 を使用する方がはるかに簡単ですif

let test x y =
  if x < y then printfn "less than"
  elif x > y then printfn "greater than"
  else printfn "equal"

あなたのmatchでは、実際には変数をバインドする必要はありません-しかし、ジョンによる解決策は、それを機能させる方法を示しています-それは単に、変数を取りxyそれらを新しい変数に割り当てるxだけですy(同じ名前を持つ)。

于 2013-09-06T03:58:17.807 に答える
15

より良いバージョンは、次のように両方の数字でパターンマッチすることです

let test x y =
   match (x,y) with
   | (x,y) when x < y -> printfn "less than"
   | (x,y) when x > y -> printfn "greater than"
   | _ -> printfn "equal"
于 2013-09-06T03:58:22.300 に答える
6

使用するパターン マッチングの種類についてパターン マッチング (F#)に相談すると、いわゆる変数 patternになります。この場合、一致ケース内の新しい変数yに match expression の値が割り当てられますx。ステートメント内のこのy変数は元の関数パラメーターを隠しているため、最初と2番目のケースでは単に の値を取得しているため、ガードは両方とも失敗します。次に、3 番目のキャッチオール マッチ ケースが開始されるため、観察されたように「等しい」リターンが得られます。matchyyxwhen_

次のスニペットを調べると、何が起こるかをよりよく理解できます。

let f x y =
    match x with
    | y -> y

次のようなもので試してみてくださいf arg1 arg2; 値に関係なくf常に返されます。arg1arg2

引数の比較を式に移動することにより、定数パターンとのマッチングを引き続き使用して、元の意図をmatch表現できます。

let test x y =
    match sign (Operators.compare x y) with
    | 1 -> "greater than"
    | -1 -> "less then"
    | _ -> "equal"
于 2013-09-06T04:00:11.103 に答える
3

ジョン・パーマーの答えに似ています。このように書くと、何が起こっているのか理解が深まると思います。

let test x y = 
    match (x,y) with
    | (a,b) when a < b -> printfn "less than"
    | (a,b) when a > b -> printfn "greater than"
    | _ -> printfn "equal"

簡単に言えば、ステートメントを使用する場合Match、パターン内の用語 (つまり の前の部分->) が新しい識別子を宣言します。yパターンで再利用すると、以前の識別子が非y表示になり、一致するものと同じ値を持つ新しい識別子 (この場合は identifier ) が作成されxます。つまり、常に の値xをそれ自体と比較しています。他の人が指摘したように、これはおそらくifステートメントで行うのが最善です。

于 2013-09-06T18:34:50.450 に答える