【问题标题】:F#: pattern matching on base typesF#:基本类型的模式匹配
【发布时间】:2018-05-05 19:38:23
【问题描述】:

我有一系列验证函数想放入数组中执行:

type result = {D: int; E: int; F: int; G: int}

type InvalidReason =
| AAA
| BBB
| CCC
| DDD
| EEE

type Validation =
| Valid
| Invalid of InvalidReason

let validators = [|AAA; BBB; CCC; DDD; EEE|]

let validateStuff result =
    validators
    |> Array.map(fun v -> v result)
    |> Array.contains(Validation.Invalid _)

问题在于最后一行代码。我得到一个“表达式中的意外值 _”。以下确实有效

|> Array.contains(Validation.Valid)
|> Array.contains(Validation.Invalid InvalidReason.AAA)

但我不想详细说明 InvalidReasons 的每个子类型。有没有我忽略的语法?

【问题讨论】:

    标签: f#


    【解决方案1】:

    函数Array.contains 接受一个值并检查该值是否在数组中。你要做的是给它一大堆值来检查。好吧,这行不通:该函数只需要一个。而且 F# 中没有类似的语法也无济于事 :-)

    您可能会使用另一个接受多个值的函数,但完成您想要的更好的方法是使用一个接受谓词的函数 - Array.exists。让自己成为一个谓词来检查一个值是否“无效”:

    let isInvalid x = match x with
        | Valid -> false
        | Invalid _ -> true
    

    并将其传递给Array.exists:

    let validateStuff result = 
        validators 
        |> Array.map(fun v -> v result) 
        |> Array.exists isInvalid
    

    或者您甚至可以将该函数内联:

    let validateStuff result = 
        validators 
        |> Array.map(fun v -> v result) 
        |> Array.exists ( fun x -> match x with
                | Valid -> false
                | Invalid _ -> true )
    

    甚至更短,使用 function 关键字:

    let validateStuff result = 
        validators 
        |> Array.map(fun v -> v result) 
        |> Array.exists ( function | Valid -> false | Invalid _ -> true )
    

    甚至更短,尽可能消除噪音:

    let validateStuff result = 
        validators 
        |> Array.map(fun v -> v result) 
        |> Array.exists ( function Invalid _ -> true | _ -> false )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多