【问题标题】:Active Pattern in match clause匹配子句中的活动模式
【发布时间】:2019-01-11 08:07:35
【问题描述】:

我正在努力更好地理解活动模式的工作原理 - 如果我读错了活动模式,请纠正我,举个例子:

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

有没有更好的阅读方式?

【问题讨论】:

    标签: f#


    【解决方案1】:

    在您的示例中,您将两个patterns 组合在一起:单个案例active recognizer 没有参数UpperCase 与常量模式"FOO"。效果确实和在 match 表达式中应用函数 (|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"
    

    【讨论】:

      【解决方案2】:

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

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

      可能是:

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

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

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

      本质上是:

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

      您正在匹配通过调用推送“foo”的结果,您不必使用通常的函数调用语法指定它。

      要回答您的其他问题,在这种特殊情况下,您可以很好地做到这一点:

      let UpperCase (x:string) = x.ToUpper()
      
      match UpperCase "foo" with
      | "FOO" -> true
      | _ -> false
      

      当您可能有多个要匹配的模式结果时,这样做会变得有点困难,而这正是活动模式更有用的地方。

      例如:

      let (|IsInt|IsString|) (x:obj) = match x with :? int -> IsInt | _ -> IsString
      
      match someValue with
      | IsInt -> true
      | IsString -> false
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-26
        • 2017-08-06
        相关资源
        最近更新 更多