在 F# 中,是否有一种标准的逻辑组合谓词的方法?
例如,假设我有 isCar x
和 isBlue x
,我想要得到某个东西:
let isBlueCar x = isCar x && isBlue x
但是使用一种组合而不是调用的方式,可能像这样:
let isBlueCar x = isCar && isBlue
最好是这个东西能够接受大量或任意数量的谓词。
在 F# 中,是否有一种标准的逻辑组合谓词的方法?
例如,假设我有 isCar x
和 isBlue x
,我想要得到某个东西:
let isBlueCar x = isCar x && isBlue x
但是使用一种组合而不是调用的方式,可能像这样:
let isBlueCar x = isCar && isBlue
最好是这个东西能够接受大量或任意数量的谓词。
let (<&>) f g = (fun x -> f x && g x)
然后执行let isBlueCar = isCar <&> isBlue
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
没有标准库函数可以实现此功能,但是您可以自己定义许多一行代码的函数,这些答案已经证明了这一点。
您可以像以下示例一样进行操作:
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]
let isBlueCar = (|>) >> flip List.forall predicates
- Ramon Snirflip
定义在哪里? - Good Night Nerd Pridelet flip f a b = f b a
- Ramon Snir这是你想要的吗?
> let (&&<) a b x = a x && b x
val ( &&< ) : ('a -> bool) -> ('a -> bool) -> 'a -> bool
> let isBlueCar = isCar &&< isBlue
val isBlueCar : (int -> bool)