2012-06-01 12 views
20

¿Existe una forma estándar de combinar predicados lógicamente en F #? Por ejemplo, digamos que tengo isCar x y isBlue x entonces quiero algo que me da:Combinación de predicados en F #

let isBlueCar x = isCar x && isBlue x 

Pero el uso de algún tipo de composición, en lugar de invocación, tal como:

let isBlueCar x = isCar && isBlue 

Preferentemente, que algo podría aceptar una cantidad grande/arbitraria de predicados.

Respuesta

21

Podría definir un combinador.

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

luego hacer

let isBlueCar = isCar <&> isBlue 
+3

... y realmente es así de fácil, ¿eh? Me encanta F #. – GregRos

+0

@GregRos - echa un vistazo a FParsec (http://www.quanttec.com/fparsec), una biblioteca de análisis maravillosamente elaborada construida utilizando el enfoque de combinadores :-) – theburningmonk

+0

Tengo: P Estoy escribiendo código en este momento:) – GregRos

2

¿Esto es lo que estás buscando?

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

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

> let isBlueCar = isCar &&< isBlue 

val isBlueCar : (int -> bool) 
4

que podría hacer algo como lo siguiente:

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

De manera más general:

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

let isBlueCar = combinePredicates [isCar;isBlue] 
+1

O en sintaxis sin puntos: 'let isBlueCar = (|>) >> flip List.forall predicados' –

+0

@RamonSnir ¿Dónde se define' flip'? –

+0

@GoodNightNerdPride No creo que esté incorporado, debe definirlo usted mismo: 'let flip f a b = f b a' –

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) 

como en

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 

No hay función de la biblioteca estándar para ella, pero hay una gran cantidad de una sola línea que se pueden definir por su cuenta, como lo demuestran las respuestas aquí.

Cuestiones relacionadas