匹配子句中的活动模式

时间:2019-01-10 21:48:55

标签: f#

我试图更好地理解活动模式的工作原理-如果我读错了活动模式,请更正我,以下面的示例为例:

let (|UpperCase|) (x:string) = x.ToUpper()

let result = match "foo" with
                 | UpperCase "FOO" -> true
                 | _ -> false

我看到我们正在比较

(Uppercase "foo") with "FOO"

但是当我阅读

时,在这种情况下看起来很奇怪
| UpperCase "Foo"

此代码不应像

那样编写
let result = match UpperCase "foo" with

有更好的阅读方法吗?

2 个答案:

答案 0 :(得分:3)

在您的示例中,您要组合两个patterns:不带参数UpperCase且具有常量模式"FOO"的单个大小写active recognizer。效果的确与您在匹配表达式中应用函数(|UpperCase|)的效果相同:

match "foo" with
| UpperCase "FOO" -> true
| _ -> false
// val it : bool = true

match (|UpperCase|) "foo" with
| "FOO" -> true
| _ -> false
// val it : bool = true

现在,将常量与常量匹配不是很通用,因此让我们创建一个函数。

let isFooBarCaseInsensitive = function
| UpperCase "FOO" | UpperCase "BAR" -> true
| _ -> false
// val isFooBarCaseInsensitive : _arg1:string -> bool
isFooBarCaseInsensitive "foo"
// val it : bool = true
isFooBarCaseInsensitive "fred"
// val it : bool = false

模式不仅用于matchfunction关键字,而且还用于try...withfun,尤其是let

let (UpperCase foo) = "foo"
// val foo : string = "FOO"

答案 1 :(得分:2)

将匹配视为简化的if / else链。例如:

index.html

可能是:

match "foo" with
| "foo" -> true    
| _ -> false

活动模式是隐式函数调用。在您的示例中:

if "foo" = "foo" then true
else false

本质上是:

match "foo" with
| UpperCase "FOO" -> true
| _ -> false

您要匹配在调用中推送“ foo”的结果,而不必使用通常的函数调用语法进行指定。

要回答您的其他问题,在这种情况下,您可以很好地达到相同的效果:

if (UpperCase "foo") = "FOO" then true
else false

当您想要匹配多个模式结果时,要执行此操作变得有些困难,这是“主动模式”更有用的地方。

例如:

let UpperCase (x:string) = x.ToUpper()

match UpperCase "foo" with
| "FOO" -> true
| _ -> false