Last active
November 18, 2019 09:05
-
-
Save stijnmoreels/feabdf5c390e4c11fb11b81f436ba96b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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