我正在尝试使用OR模式,如这里所述:
let foo = function
| Some (0, x) when x > 0 | None -> "bar"
| _ -> "baz"
然而,这样会导致编译错误:
我做错了什么?这与error FS0010:在模式匹配中出现意外符号'|'。应该期望的是'->'或其他标记。
when
保护有关吗?我正在尝试使用OR模式,如这里所述:
let foo = function
| Some (0, x) when x > 0 | None -> "bar"
| _ -> "baz"
我做错了什么?这与error FS0010:在模式匹配中出现意外符号'|'。应该期望的是'->'或其他标记。
when
保护有关吗?when
保护语句针对单个情况进行判断,不论有多少个模式组合。这些情况需要分开写:
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"
let (|Bar|_|) = function
| Some(0, x) when x > 0 -> Some()
| None -> Some()
| _ -> None
let foo = function
| Bar -> "bar"
| _ -> "baz"
在这里你需要两个不同的匹配情况,因为这两种情况绑定了不同的变量集合(分别是x
和空):
| 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