结合F#中的谓词

时间:2012-06-01 16:24:19

标签: .net f# functional-programming composition

在F#中是否存在逻辑组合谓词的标准方法? 例如,假设我有isCar xisBlue x,那么我想要一些能给我的东西:

let isBlueCar x = isCar x && isBlue x

但是使用某种组合而不是调用,可能就像:

let isBlueCar x = isCar && isBlue

最好能够接受大量/任意数量的谓词。

4 个答案:

答案 0 :(得分:23)

您可以定义组合子。

let (<&>) f g = (fun x -> f x && g x)

然后做

let isBlueCar = isCar <&> isBlue

答案 1 :(得分:5)

let meetsAll preds = preds |> Seq.fold (fun p q x -> p x && q x) (fun _ -> true)
// or     let meetsAll preds x = preds |> Seq.forall (fun p -> p x)

,如

let isEven x = x%2 = 0
let isDiv5 x = x%5 = 0
let isDiv7 x = x%7 = 0

let div257 = meetsAll [isEven; isDiv5; isDiv7]

for i in 1..100 do
    if div257 i then
        printfn "%d" i

它没有标准的库函数,但是你可以自己定义过多的单行,这里的答案可以证明。

答案 2 :(得分:4)

您可以执行以下操作:

let predicates = [isCar; isBlue]
let isBlueCar x = predicates |> List.forall (fun predicate -> predicate x)

更一般地说:

let combinePredicates predicates =
    fun x -> predicates |> List.forall (fun predicate -> predicate x)

let isBlueCar = combinePredicates [isCar;isBlue]

答案 3 :(得分:2)

这是你要找的吗?

> let (&&<) a b x = a x && b x

val ( &&< ) : ('a -> bool) -> ('a -> bool) -> 'a -> bool

> let isBlueCar = isCar &&< isBlue

val isBlueCar : (int -> bool)