Skip to content

Instantly share code, notes, and snippets.

@stijnmoreels
Last active November 18, 2019 09:05
Show Gist options
  • Save stijnmoreels/feabdf5c390e4c11fb11b81f436ba96b to your computer and use it in GitHub Desktop.
Save stijnmoreels/feabdf5c390e4c11fb11b81f436ba96b to your computer and use it in GitHub Desktop.
type Author =
private Author of string with
static member create x =
let name = @"[A-Z]{1}[a-z]*\.?"
let pattern = sprintf "^(%s)( %s)*$" name name
specModel Author x {
notNullOrWhiteSpace "author name should not be blank"
greaterThanOrEqualOf String.length 1 "author name should at least be a single character"
matches pattern "author name should only contain names starting with a capital" }
type ISBN13 =
private ISBN13 of string with
static member create x =
let checksum (code : string) =
let digits = code.ToCharArray() |> Seq.map (string >> int)
let sum =
Seq.take 12 digits
|> Seq.mapi (fun i n -> if i % 2 <> 0 then n * 3 else n)
|> Seq.sum
let rem = sum % 10
let checksum = if rem <> 0 then 10 - rem else rem
checksum = Seq.last digits
specModel ISBN13 x {
notNullOrWhiteSpace "ISBN13 number should not be blank"
equalOf String.length 13 "ISBN13 number should be 13 characters"
matches "^[0-9]+$" "ISBN13 number should only contain numbers"
startsWith "987" "ISBN13 number should start with '987'"
verify checksum "ISBN13 checksum was invalid" }
type Int1000 =
private Int1000 of int with
static member create x = specModel Int1000 x {
inclusiveBetween 1 1000 "integer number must be between 1-1000" }
type Book =
{ Author : Author
ISBN13 : ISBN13
Pages : Int1000 } with
static member create author isbn13 pages = result {
let! author = Author.create author
let! isbn13 = ISBN13.create isbn13
let! pages = Int1000.create pages
return { Author = author; ISBN13 = isbn13; Pages = pages } }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment