FsCheck offers the Gen.filter / Gen.where functions. Example:
type Status = Pending | Activated | Deactivated
type Item = { Id: int; Status: Status }
let nonPendingItemGen =
Arb.generate
|> Gen.filter (fun item -> item.Id > 0 && item.Status <> Pending }
Is it possible to refactor this code to use gen computation expression with the "filter" inside?
- A quick attempt using an
ifstatement failed because of the type discrepancies between theifand theelsebranches. - I found a solution by generating a sequence and then filter this sequence but I find it less elegant.
You can do this by generating a valid ID and status within the computation expression and then constructing the item from those values. Instead of thinking about what values you don't want, think about the values you do want and generate them:
This approach is more efficient in general, because you don't waste time generating (and then rejecting) invalid items.
Note that I've used FsCheck's built-in
PositiveInttype. Alternatively, you could generate a positive integer directly via: