7 people like it.

Simple validation using functions

This is a "library" for validation that collects all validation errors (and does not use the heavy-weight machinery of monads). This is perhaps a simpler variant that could be used e.g. here: http://tinyurl.com/lv2nwkl

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
/// Validation can succeed or report a list
/// of validation error messages 
type ValidationResult = 
  | OK
  | Invalid of string list

// Validation #1 - check that name is not empty
let validateName (name:string, _, _) =
  if name = "" then Invalid ["Name cannot be empty"]
  else OK

// Validation #2 - check that passwords match
let validatePass (_, pass1, pass2) = 
  if pass1 <> pass2 then Invalid ["Passwords do not match"]
  else OK

// Validation #3 - check that password is long enough
let validatePassLen (_, pass:string, _) = 
  if pass.Length < 5 then Invalid ["Passwords too short"]
  else OK

// When combining two validation functions, we pass the input 'x' to
// both of them. Then we either return OK, if both returned OK, or
// we collect error messages from both funtions
let (<&>) f1 f2 x = 
  match f1 x, f2 x with
  | OK, OK -> OK
  | Invalid e1, Invalid e2 -> Invalid (e1 @ e2)
  | Invalid e, OK | OK, Invalid e -> Invalid e

// Now we can compose validation functions
// (to get function that reports all errors)
let validate = 
  validateName <&>
  validatePass <&>
  validatePassLen

validate ("Tomas", "pa", "password")
union case ValidationResult.OK: ValidationResult
union case ValidationResult.Invalid: string list -> ValidationResult
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val validateName : name:string * 'a * 'b -> ValidationResult

Full name: Script.validateName
val name : string
val validatePass : 'a * pass1:'b * pass2:'b -> ValidationResult (requires equality)

Full name: Script.validatePass
val pass1 : 'b (requires equality)
val pass2 : 'b (requires equality)
val validatePassLen : 'a * pass:string * 'b -> ValidationResult

Full name: Script.validatePassLen
val pass : string
property System.String.Length: int
val f1 : ('a -> ValidationResult)
val f2 : ('a -> ValidationResult)
val x : 'a
val e1 : string list
val e2 : string list
val e : string list
val validate : (string * string * string -> ValidationResult)

Full name: Script.validate
Raw view Test code New version

More information

Link:http://fssnip.net/q4
Posted:9 years ago
Author:Tomas Petricek
Tags: validation , library