F#:基类型的模式匹配

时间:2018-05-05 19:38:24

标签: 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 _)

问题在于最后一行代码。我在表达式中得到了“意外的值_”。以下工作

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

但我不想拼出InvalidReasons的每个子类型。是否有一些我忽略的语法?

1 个答案:

答案 0 :(得分:6)

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

您可能使用另一个带有多个值的函数,但更好的方法是使用一个带谓词的函数 - this。让自己成为一个谓词,检查一个值是否为"无效":

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 )
相关问题