I am creating a type system for some generic types of common input:
// type Validator<'t> when 't :> ??? = Validator of 't
// with member x.validate value condition =
// if condition then
// (true, Some ('t value))
// else
// (false, None)
module Validatable =
let validate t value condition =
if condition then
(true, Some (t value))
else
(false, None)
type Email = Email of string
with member x.validate(s) = Validatable.validate Email s (Regex.IsMatch(s, ""))
type Name = Name of string
with member x.validate(s) = Validatable.validate Name s (Regex.IsMatch(s, ""))
type PhoneNumber = PhoneNumber of string
with member x.validate(s) = Validatable.validate PhoneNumber s (Regex.IsMatch(s, ""))
You'll see that within the comment, I have another type commented out. I am hoping to use the type defined within the comment to replace the functionality of the validate t value condition
function within the Validatable
module.
What do I need to replace the ??? with to allow me to say that the generic parameter 't
is the case identifier of a Discriminated Union?
A union case isn't a type, it's a function that produces a value of type. So you can write your Validator
type like this instead:
type Validator<'inp, 'out> = Validator of ('inp -> 'out)
with member x.validate value condition =
let (Validator f) = x
if condition then
(true, Some (f value))
else
(false, None)
And use it like this:
type Email = Email of string
with member x.validate(s) = (Validator Email).validate s (Regex.IsMatch(s, ""))
type Name = Name of string
with member x.validate(s) = (Validator Name).validate s (Regex.IsMatch(s, ""))
type PhoneNumber = PhoneNumber of string
with member x.validate(s) = (Validator PhoneNumber).validate s (Regex.IsMatch(s, ""))