F#:基类型的模式匹配

Jam*_*xon 3 f#

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

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 _)
Run Code Online (Sandbox Code Playgroud)

问题是最后一行代码.我在表达式中得到了"意外的值_".以下工作正常

|> Array.contains(Validation.Valid)
|> Array.contains(Validation.Invalid InvalidReason.AAA)
Run Code Online (Sandbox Code Playgroud)

但我不想拼出InvalidReasons的每个子类型.我有一些语法可以忽略吗?

Fyo*_*kin 6

该函数Array.contains接受一个值并检查该值是否在数组中.你要做的是给它一大堆值来检查.嗯,这不起作用:该功能只需要一个.在F#中没有类似的语法也无济于事:-)

您可能使用另一个具有多个值的函数,但更好的方法来实现您想要的是使用一个带谓词的函数 - Array.exists.自己做一个谓词来检查一个值是否"无效":

let isInvalid x = match x with
    | Valid -> false
    | Invalid _ -> true
Run Code Online (Sandbox Code Playgroud)

并传递给Array.exists:

let validateStuff result = 
    validators 
    |> Array.map(fun v -> v result) 
    |> Array.exists isInvalid
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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