Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FsCheck Generator support #3

Open
farlee2121 opened this issue Dec 15, 2020 · 2 comments
Open

FsCheck Generator support #3

farlee2121 opened this issue Dec 15, 2020 · 2 comments

Comments

@farlee2121
Copy link

I found your library while thinking of how I could better handle Type-Driven Design constraints.
I like the way your library lets users bring their own validation errors.

Another benefit I'd like from this approach is type-driven generative testing like is available with Clojure Spec. In other words, property testing where the property is the type validators (or for any valid input we get valid output based on given constraints).

This can be achieved fairly easily if the validator can feed into an FsCheck generator. That doesn't seem to be supported as is, but would be possible if constraints were aggregated in a type, monad/applicative style, so that different consumers could interpret the rules differently. The key bit is that the .Validate would need to return a Monad instead directly returning the error type.

Is this a use case you have given thought to? Thoughts?

@lfr
Copy link
Owner

lfr commented Dec 16, 2020

Interesting, I haven't thought about this but it seems pretty easy to implement unless there's something I haven't considered, I'll definitely take a look at it at the same time as I work on #2 (closed by reporter but still valid imo)

@farlee2121
Copy link
Author

I was able to make a decent prototype validation data structure last night.

type Constraint<'a> = 
    | MaxLength of int
    | MinLength of int
    | Regex of string
    | Max of 'a 
    | Min of 'a
    | Choice of 'a list
    | And of Constraint<'a> list
    | Or of Constraint<'a> list
    | Custom of string * ('a -> bool) 

It's pretty easy to construct complex validations with a few simple combinators and constructors

let (&&&) left right = And [left; right]
let (|||) left right = Or [left; right]
let matchRegex pattern = Regex pattern
let max = (Max)
//... 

This collapses down to a validation result via catamorphism pretty predictably. But I got stuck on on the generator catamorphism, the main issue being no clear concept of And for generators. Ranges, or, choice, filter, and even regex have pretty easy mappings.

This form is still pretty useful though. It makes it straight forward interpret constraints many ways: validation, explainer, serializers, other validation libraries, generators (hopefully).

I'll let you know if I have any breakthroughs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants