このエラーが発生する理由は、一致式のパターン句で変数名を使用するときに F# が行っていることです。
私が持っているとしましょう
match arg with
| x when x = 0 -> "zero"
| y when y = 1 -> "one"
| _ -> "other"
一致する前に x または y を定義していなくても、このコードは機能することに注意することがここで重要だと思います。これは、x と y がマッチ式の記述を容易にする単なる短いコードであるためです。舞台裏で、F# コンパイラは実際にそれx when x = 0
を "let バインディング"に変換しx
ていarg
ます。 その後、式および の後の式でx
使用できます。x = 0
->
遭遇した問題に戻ります。
let key1 = 1
let key2 = 2
let value =
match arg with
| key1 -> "value1"
| key2 -> "value2"
| _ -> failwith "key not found"
これが機能しない理由は、一致式で F# がkey1
の値に再バインドされているarg
ためです。したがってkey1 -> "value1" is equivalent to
、arg1 = arg1 の場合は "value1". 最初のパターンは常に一致します。そのため、決して到達することはありませんkey2
。_
私の説明がどれほど明確かはわかりません。そのため、何が起こったのかを説明するための 2 番目のアプローチも投入します。
一致式を if-else に変換すると、次のようになります。
let key1 = 1
let key2 = 2
let value =
if let key1 = arg in arg = key1 then
"value1"
else if let key2 = arg in arg = key2 then
"value2"
else
failwith "key not found"
(そうです。F# では、let バインディングを if 式にスローできます)
この if/else 式は、一致式と同等です。この形式では、最初の条件が常に true と評価されることが明らかになります。
ここには入れませんが、一致式のコード クォーテーションを参照すると役立つ場合があります。生成された抽象構文ツリーがどのように見えるかを見るまで、マッチ式で何が起こっているのかを実際に理解することはできませんでした。