【问题标题】:In F#, return true if expression matches pattern?在 F# 中,如果表达式匹配模式,则返回 true?
【发布时间】:2014-03-09 16:44:21
【问题描述】:

我正在寻找一种更短/更简洁的方法来执行以下等效操作(对于编译时已知的任何模式):

let f x = match x with | ['A'::_] -> true ; | _ -> false

一般来说有没有办法做到这一点,即如果表达式匹配给定模式,则返回 true?

【问题讨论】:

    标签: f# pattern-matching


    【解决方案1】:

    您可以使用function 稍微缩短它:

    let f = function ['A'::_] -> true | _ -> false
    

    【讨论】:

    • 又近了一步,不是吗?没有将模式匹配或不转换为真/假的语法,也没有办法将“模式”传递给另一个函数来构建一个..?
    【解决方案2】:

    在 f# 中,模式本身并不是值,并且没有将它们转换为值 (*) 的机制。所以,不,没有更整洁的方法。

    也就是说,您可能还有其他选择,具体取决于您为什么您有兴趣检查模式是否匹配。关心模式是否匹配而不关心匹配的值对我来说似乎有点不寻常,所以也许有重构的机会。

    举个简单的例子,假设你这样做:

    let t = match e with <pattern> -> true | _ -> false 
    ...
    if t then
        (* Do something. *)
    else 
        (* Do something else. *)
    ...
    

    在这种情况下,您可以考虑这样做:

    ...
    match e with 
      <pattern> -> (* Do something. *)
    | _         -> (* Do something else. *)
    ...
    

    (当然,假设测试只发生一次。)

    (*) 忽略 reflectionquotations

    【讨论】:

      【解决方案3】:

      您可能在这里想到了一个活动模式,特别是它的单例形式。它允许您创建一个返回布尔值的模式:

      let (|F|) = function 
          | ['A'::_] -> true
          | _ -> false
      
      let (F x) = [['A']] // val x : bool = true
      

      活动模式可以参数化。它接受的 (n + 1) 个参数中,第一个 n 被传递给语法函数,最后一个参数是匹配的值。

      let (|G|) e = function
          | [d::_] when d = e -> true
          | _ -> false
      
      let (G 'A' y) = [['A']] // val y : bool = true
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-19
        • 2018-01-15
        • 2022-01-14
        相关资源
        最近更新 更多