уменьшить список функций до логического значения

Я ищу способ уменьшить этот список до логического значения. Вот оригинал:

let ones = [1;1;1;1]
let twos = [2;2;2;2]
let bad = [1;2;3]

let isAllOnes = List.forall (fun op -> op = 1)
let isAllTwos = List.forall (fun op -> op = 2)  

let isOneOrTwo ops = isAllOnes ops || isAllTwos ops

isOneOrTwo ones |> should be True
isOneOrTwo twos |> should be True
isOneOrTwo bad |> should be False

Я пытаюсь реорганизовать это, используя своего рода сокращение. Что-то вроде этого:

let isOneOrTwo ops = [isAllOnes; isAllTwos] |> List.tryFind (fun acc -> acc ops) 

(isOneOrTwo ones).IsSome |> should be True
(isOneOrTwo twos).IsSome |> should be True
(isOneOrTwo bad).IsSome |> should be False

Мне не нравится, как isOneOrTwo сводится к Option. Я действительно хотел бы уменьшить список до логического значения, чтобы мои утверждения могли выглядеть так:

isOneOrTwo ones |> should be True
isOneOrTwo twos |> should be True
isOneOrTwo bad |> should be False

Кто-нибудь знает, как это сделать? List.reduce не работал, потому что типы были разными.


person Paul Nikonowicz    schedule 03.05.2012    source источник


Ответы (1)


Замените List.tryFind на List.exists

let ones = [1;1;1;1]
let twos = [2;2;2;2]
let bad = [1;2;3]

let allOnes = List.forall ((=) 1)
let allTwos = List.forall ((=) 2)

let isOneOrTwo l = [allOnes; allTwos] |> List.exists (fun f -> f l)

printfn "%A " (isOneOrTwo ones) // true
printfn "%A " (isOneOrTwo twos) // true
printfn "%A " (isOneOrTwo bad)  // false
person desco    schedule 03.05.2012
comment
Вау, мне нравится такое чистое и простое решение. - person Onorio Catenacci; 03.05.2012