Ответ 1
Вы можете определить комбинатор.
let (<&>) f g = (fun x -> f x && g x)
то do
let isBlueCar = 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)
то do
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 (&&<) a b x = a x && b x
val ( &&< ) : ('a -> bool) -> ('a -> bool) -> 'a -> bool
> let isBlueCar = isCar &&< isBlue
val isBlueCar : (int -> bool)