consideri un'Unione Discriminazione in:Come filtrare facilmente un caso sindacale discriminato in FsCheck?
type DU = | Foo of string | Bar of int | Baz of decimal * float | Qux of bool
Mi piacerebbe creare un elenco di valori con DU
FsCheck, ma voglio nessuno dei valori sia del caso Qux
.
Questo predicato esiste già:
let isQux = function Qux _ -> true | _ -> false
Primo tentativo
Il mio primo tentativo di creare un elenco di DU
valori senza il caso Qux
era qualcosa di simile:
type DoesNotWork =
static member DU() = Arb.from<DU> |> Arb.filter (not << isQux)
[<Property(MaxTest = 10 , Arbitrary = [| typeof<DoesNotWork> |])>]
let repro (dus : DU list) =
printfn "%-5b : %O" (dus |> List.exists isQux |> not) dus
L'esecuzione di questo sembra produrre uno stack overflow, quindi presumo che ciò che ha ppens dietro la scena è che Arb.from<DU>
chiama DoesNotWork.DU
.
Secondo tentativo
Poi ho provato questo:
type DoesNotWorkEither =
static member DU() =
Arb.generate<DU>
|> Gen.suchThat (not << isQux)
|> Arb.fromGen
[<Property(MaxTest = 10 , Arbitrary = [| typeof<DoesNotWorkEither> |])>]
let repro (dus : DU list) =
printfn "%-5b : %O" (dus |> List.exists isQux |> not) dus
Stesso problema di cui sopra.
soluzione dettagliato
Questa è la soluzione migliore che ho potuto venire con finora:
type WithoutQux =
static member DU() =
[
Arb.generate<string> |> Gen.map Foo
Arb.generate<int> |> Gen.map Bar
Arb.generate<decimal * float> |> Gen.map Baz
]
|> Gen.oneof
|> Arb.fromGen
[<Property(MaxTest = 10 , Arbitrary = [| typeof<WithoutQux> |])>]
let repro (dus : DU list) =
printfn "%-5b : %O" (dus |> List.exists isQux |> not) dus
Questo funziona, ma ha i seguenti svantaggi:
- Sembra un sacco di lavoro
- Non utilizza il già disponibileFunzione, quindi sembra sottilmente violare DRY
- Non è proprio il filtro , ma produce solo i casi desiderati (quindi filtri solo per omissione).
- Non è particolarmente gestibile, perché se aggiungo mai un quinto caso a
DU
, dovrei ricordare aggiungere anche unoGen
per quel caso.
C'è un modo più elegante per dire a FsCheck di filtrare i valori Qux
?
Bene, questo aggira il problema creando un 'Arbitrario' invece di un 'Arbitrario ', che può ve il mio problema immediato, ma non sembra affrontare il problema di fondo. –
Questo non pone il problema che non otteniamo il supporto restringente per il DU? – Henrik