Skip to content

Instantly share code, notes, and snippets.

@jfrank-summit
Last active April 15, 2019 17:35
Show Gist options
  • Save jfrank-summit/2a692b473596368f529a1715f499846d to your computer and use it in GitHub Desktop.
Save jfrank-summit/2a692b473596368f529a1715f499846d to your computer and use it in GitHub Desktop.
F# Signature File - Constrained Types
module StringConstraints
open System
let stringPattern str pattern =
if String.IsNullOrEmpty(str) then
let msg = sprintf "%s: Must not be null or empty" str
Error msg
elif System.Text.RegularExpressions.Regex.IsMatch(str, pattern) then
Ok (str)
else
let msg = sprintf "'%s' must match the pattern '%s'" str pattern
Error msg
type EmailAddress (emailAddress:string) =
member x.Value =
let pattern = @"^\S+@\S+\.\S+$"
stringPattern emailAddress pattern
module StringConstraints
val stringPattern : string -> string -> Result<string, string>
//[<Sealed>]
type EmailAddress =
new : string -> EmailAddress
member Value : Result<string, string>
@jfrank-summit
Copy link
Author

jfrank-summit commented Aug 3, 2018

I was reading Domain Driven Design (A GREAT BOOK!) by Scott Wlaschin, one of the best F# sites!. On page 106 he shows how to jump through some hoops to add a "create" function that checks for constraints on a type. How it was shown felt very hacky (but effective). However, there was a kind of throw away line about there being "other tecniques, such as using signature files, but we won't discuss them here." WHY? Well, I decided it was time I learn about these "signature files" and how they can be used for constraints. And the above is quick hack that seems to work! And it doesn't feel nearly as dirty as the method shown in the book... Thoughts?

@tamizhvendan
Copy link

I use this approach a lot and found it very useful! @jfrank-summit

@jfrank-summit
Copy link
Author

your approach seems to make most sense to me! @tamizhvendan

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