2012-06-01 91 views
20

有沒有一種在F#中將謂詞邏輯組合的標準方式? 例如,假設我有isCar xisBlue x然後我想要的東西,給我:在F#中結合謂詞

let isBlueCar x = isCar x && isBlue x 

但是,使用某種成分,而不是調用,也許像:

let isBlueCar x = isCar && isBlue 

優選地,有些東西可以接受大量/任意數量的謂詞。

回答

21

您可以定義一個組合子。

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

然後做

let isBlueCar = isCar <&> isBlue 
+3

...真的很簡單,呵呵?我喜歡F#。 – GregRos

+0

@GregRos - 查看FParsec(http://www.quanttec.com/fparsec),這是一個使用combinators方法構建的精美的解析庫:-) – theburningmonk

+0

我有:P我正在寫代碼: ) – GregRos

2

這是你在找什麼?

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

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

> let isBlueCar = isCar &&< isBlue 

val isBlueCar : (int -> bool) 
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] 
+1

或者使用無點語法:'let isBlueCar =(|>)>> flip List.forall predicates' –

+0

@RamonSnir'flip'的定義在哪裏? –

+0

@GoodNightNerdPride我不認爲它是內置的,你需要自己定義它:'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) 

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 

有沒有爲它的標準庫函數,但也有你可以定義你自己的,由這裏的答案證明的俏皮話太多了。