ここで説明されているように、ORパターンを使用しようとしています:
let foo = function
| Some (0, x) when x > 0 | None -> "bar"
| _ -> "baz"
ただし、これによりコンパイラ エラーが発生します。
エラー FS0010: 予期しないシンボル '|' パターンマッチングで。'->' またはその他のトークンが必要です。
私は何を間違っていますか?警備員と関係あるのwhen
?
ここで説明されているように、ORパターンを使用しようとしています:
let foo = function
| Some (0, x) when x > 0 | None -> "bar"
| _ -> "baz"
ただし、これによりコンパイラ エラーが発生します。
エラー FS0010: 予期しないシンボル '|' パターンマッチングで。'->' またはその他のトークンが必要です。
私は何を間違っていますか?警備員と関係あるのwhen
?
ガードは、組み合わせたwhen
パターンの数に関係なく、1 つのケースを指します。ケースを分離する必要があります。
let foo = function
| Some (0, x) when x > 0 -> "bar"
| None -> "bar"
| _ -> "baz"
そのため、複雑な式が繰り返されないように、戻り値を除外する方がよい場合があります。
let foo value =
let ret = "bar"
match value with
| Some (0, x) when x > 0 -> ret
| None -> ret
| _ -> "baz"
このような繰り返しを避けるもう 1 つの方法は、アクティブなパターンを使用することです。
let (|Bar|_|) = function
| Some(0, x) when x > 0 -> Some()
| None -> Some()
| _ -> None
let foo = function
| Bar -> "bar"
| _ -> "baz"
x
2つのケースは異なる変数のセットをバインドするため(それぞれ、何もバインドしないため)、2つの別々の一致ケースが必要になります。
| Some(0, x) when x>0 -> "bar"
| None -> "bar"
非常に複雑なパターンでラベルの特定のバインディングのみを保護したい場合に、私が時々使用する便利なトリックは、独自のアクティブなパターンと&
( and
) パターン演算子を使用することです。
let (|GreaterThan|_|) lowerLimit n =
if n > lowerLimit then Some () else None
let (|LesserThan|_|) upperLimit n =
if n < upperLimit then Some () else None
let (|GreaterOETo|_|) lowerLimit n =
if n >= lowerLimit then Some () else None
let (|LesserOETo|_|) upperLimit n =
if n <= upperLimit then Some () else None
let (|InRange|_|) (lowerLimit, upperLimit) n =
if n >= lowerLimit && n <= upperLimit then Some () else None
let (|Even|Odd|) n =
if n % 2 = 0 then
Even (n / 2)
else
Odd (n / 2)
type Union =
| A of int
| B of int
| A' of int
let getSpecialCases = function
| A (Even (x & GreaterThan 4 & LesserOETo 16))
| A (Odd (x & GreaterThan 0))
| B (x & LesserOETo 0)
| A' (Even (x & InRange (5, 16)))
| A' (Odd (x & GreaterThan 0)) -> Some x
| _ -> None
もちろん、アクティブなパターン ラッパーへの関数を作成することもできます。
let (|P|_|) pred x =
if pred x then Some () else None
let ``match`` = function
| Even (x & pred (fun x -> x >= 7 && x <= 54)) -> Some x
| _ -> None