I am new to F# and looking for a way to introduce it in our org. Specifically, I am investigating if I can use F# for easy and safe validation of C# domain objects in a web service. All validations are related to properties on objects. Examples: property must not be null/empty, field max length, field must satisfy regular expression etc.
The special thing here is that the F# code need to BOTH able to perform the validations AND expose the validation rules to the clients of the service, so GUI clients can perform pre-validation themselves by reusing a single set of validation rules (DRY principle applied across service boundaries).
So besides being able to do validation of a domain object and tell of success/failure details, the F# code must also be able to list all possible validations (ultimately in a data structure that can be converted into JSON). In addition the design must be "safe" - not referring to c# property names as "strings" etc. We should get compilation errors if a C# property is misspelled etc.
A complicated C# design exists where validation rules are classes and LINQ expressions are used to associate validation rules to properties. The LINQ expressions can then be reflected upon from C#, hence making it possible to both perform validation and return the rules themselves in C#.
So C# can do it (in a complicated way) but the questions is how to do it in F# (and better). I have seen a lot of examples of how to use F# for validation (fsharpforfunandprofit has some nice examples) but I could find none that can both execute validation and return validation rules themselves (as json-compatible structures).
The code below shows an example of a C# domain class and some very initial and unfinished F# code I have written to explore how to represent things. The F# currently use code quotations where C# use LINQ to associate properties to validation rules in a safe manner. I first thought that I could then simply evaluate the code quotations to perform validation and inspect them to output rules as JSON. However but there appear to be no build-in support for evaluation of code quotations and from what I understand it will also be slow if I do evaluate using a 3rd party library. Hence, it seems the F# solution can not compete with the C# solution.
What to do ?
C# domain class example:
public class Company
{
public string Name { get; }
public string Cvr { get; }
public Company(string name, string cvr)
{
this.Name = name;
this.Cvr = cvr;
}
}
Very raw initial F# code so far:
type Validation =
| RequiredField
| RegEx of string
| MinLength of uint32
| MaxLength of uint32
type FieldValue = string -> string
type SingleFieldValidation = FieldValue*Validation
let Validate validation (input:string) =
match validation with
| RequiredField -> not (String.IsNullOrEmpty input)
| RegEx pattern -> input<>null && Regex.Match(input, pattern, RegexOptions.IgnoreCase).Success
| MinLength min -> input<>null && input.Length>=(int)min
| MaxLength max -> input=null || input.Length<=(int)max
let personValidations (x:Person) = [(<@ x.FirstName @>, RequiredField),(<@ x.Cpr @>, RegEx "\d{8}") ]