22// This block of code is omitted in the generated HTML documentation. Use
33// it to define helpers that you do not want to show in the documentation.
44(**
5- Validation<'Error,'T>
6- =====================
5+ Validation<'Error, 'T>
6+ ======================
77
8- This is similar to Result<'T,'Error> but with accumulative errors semantics, instead of short-circuit.
8+ This is similar to Result<'T, 'Error> but with accumulative errors semantics, instead of short-circuit.
99
1010Examples
1111--------
@@ -18,72 +18,83 @@ open System
1818open FSharpPlus
1919open FSharpPlus.Data
2020
21- module MovieValidations =
22- type VError = | MustNotBeEmpty
23- | MustBeAtLessThanChars of int
24- | MustBeADate
25- | MustBeOlderThan of int
26- | MustBeWithingRange of decimal * decimal
27- module String =
28- let nonEmpty ( x : string ) : Validation < VError list , string > =
29- if String.IsNullOrEmpty x
21+ module MovieValidations =
22+ type VError =
23+ | MustNotBeEmpty
24+ | MustBeAtLessThanChars of int
25+ | MustBeADate
26+ | MustBeOlderThan of int
27+ | MustBeWithingRange of decimal * decimal
28+
29+ module String =
30+ let nonEmpty ( x : string ) : Validation < VError list , string > =
31+ if String.IsNullOrEmpty x
3032 then Failure [ MustNotBeEmpty]
3133 else Success x
32- let mustBeLessThan ( i : int ) ( x : string ) : Validation < VError list , string > =
34+ let mustBeLessThan ( i : int ) ( x : string ) : Validation < VError list , string > =
3335 if isNull x || x.Length > i
3436 then Failure [ MustBeAtLessThanChars i]
3537 else Success x
36- module Number =
37- let mustBeWithin ( from , to' ) ( x )=
38+
39+ module Number =
40+ let mustBeWithin ( from , to' ) x =
3841 if from<= x && x <= to'
3942 then Success x
40- else Failure [ MustBeWithingRange ( from, to')]
41- module DateTime =
42- let classicMovie year ( d : DateTime )=
43+ else Failure [ MustBeWithingRange ( from, to')]
44+
45+ module DateTime =
46+ let classicMovie year ( d : DateTime ) =
4347 if d.Year < year
4448 then Success d
4549 else Failure [ MustBeOlderThan year]
46- let date ( d : DateTime )=
50+ let date ( d : DateTime ) =
4751 if d.Date = d
4852 then Success d
4953 else Failure [ MustBeADate]
50- type Genre =
51- | Classic
52- | PostClassic
53- | Modern
54- | PostModern
55- | Contemporary
54+
55+ type Genre =
56+ | Classic
57+ | PostClassic
58+ | Modern
59+ | PostModern
60+ | Contemporary
61+
5662 type Movie = {
5763 Id: int
5864 Title: String
5965 ReleaseDate: DateTime
6066 Description: String
6167 Price: decimal
6268 Genre: Genre
63- }
64- with static member Create ( id , title , releaseDate , description , price , genre ): Validation < VError list , Movie > =
65- fun title releaseDate description price -> { Id= id; Title= title; ReleaseDate= releaseDate; Description= description; Price= price; Genre= genre }
69+ } with
70+ static member Create ( id , title , releaseDate , description , price , genre ) : Validation < VError list , Movie > =
71+ fun title releaseDate description price -> { Id = id; Title = title; ReleaseDate = releaseDate; Description = description; Price = price; Genre = genre }
6672 <!> String.nonEmpty title <* String.mustBeLessThan 100 title
6773 <*> DateTime.classicMovie 1960 releaseDate <* DateTime.date releaseDate
6874 <*> String.nonEmpty description <* String.mustBeLessThan 1000 description
6975 <*> Number.mustBeWithin ( 0.0 m, 999.99 m) price
7076
71- let newRelease = Movie.Create( 1 , " Midsommar" , DateTime( 2019 , 6 , 24 ), " Midsommar is a 2019 folk horror film written..." , 1 m, Classic) //Failure [MustBeOlderThan 1960]
72- let oldie = Movie.Create( 2 , " Modern Times" , DateTime( 1936 , 2 , 5 ), " Modern Times is a 1936 American comedy film..." , 1 m, Classic) // Success..
73- let titleToLong = Movie.Create( 3 , String.Concat ( seq { 1 .. 110 }), DateTime( 1950 , 1 , 1 ), " 11" , 1 m, Classic) //Failure [MustBeAtLessThanChars 100]
77+ let newRelease = Movie.Create ( 1 , " Midsommar" , DateTime ( 2019 , 6 , 24 ), " Midsommar is a 2019 folk horror film written..." , 1 m, Classic) //Failure [MustBeOlderThan 1960]
78+ let oldie = Movie.Create ( 2 , " Modern Times" , DateTime ( 1936 , 2 , 5 ), " Modern Times is a 1936 American comedy film..." , 1 m, Classic) // Success..
79+ let titleToLong = Movie.Create ( 3 , String.Concat ( seq { 1 .. 110 }), DateTime ( 1950 , 1 , 1 ), " 11" , 1 m, Classic) //Failure [MustBeAtLessThanChars 100]
80+
81+
82+ module Person =
83+
84+ type Name = { unName: String }
85+ with static member create s = { unName = s }
86+
87+ type Email = { unEmail: String }
88+ with static member create s = { unEmail = s }
7489
75- module Person =
76- type Name = { unName : String }
77- with static member create s = { unName= s}
78- type Email = { unEmail : String }
79- with static member create s = { unEmail= s}
8090 type Age = { unAge : int }
81- with static member create i = { unAge= i }
91+ with static member create i = { unAge = i }
8292
83- type Person = { name : Name
84- email : Email
85- age : Age }
86- with static member create name email age = { name= name; email= email; age= age }
93+ type Person = {
94+ name: Name
95+ email: Email
96+ age: Age }
97+ with static member create name email age = { name = name; email = email; age = age }
8798
8899
89100 type Error =
@@ -92,21 +103,21 @@ module Person=
92103 | AgeBetween0and120
93104
94105 // Smart constructors
95- let mkName s =
106+ let mkName s =
96107 let l = length s
97108 if ( l >= 1 && l <= 50 )
98109 then Success <| Name.create s
99- else Failure [ NameBetween1And50 ]
110+ else Failure [ NameBetween1And50]
100111
101- let mkEmail s =
112+ let mkEmail s =
102113 if String.contains '@' s
103114 then Success <| Email.create s
104- else Failure [ EmailMustContainAtChar ]
115+ else Failure [ EmailMustContainAtChar]
105116
106- let mkAge a =
117+ let mkAge a =
107118 if ( a >= 0 && a <= 120 )
108119 then Success <| Age.create a
109- else Failure [ AgeBetween0and120 ]
120+ else Failure [ AgeBetween0and120]
110121
111122 let mkPerson pName pEmail pAge =
112123 Person.create
@@ -147,36 +158,37 @@ module Person=
147158module Email =
148159
149160 // ***** Types *****
150- type AtString = AtString of string
151- type PeriodString = PeriodString of string
152- type NonEmptyString = NonEmptyString of string
161+ type AtString = AtString of string
162+ type PeriodString = PeriodString of string
163+ type NonEmptyString = NonEmptyString of string
153164
154- type Email = Email of string
165+ type Email = Email of string
155166
156- type VError = | MustNotBeEmpty
157- | MustContainAt
158- | MustContainPeriod
167+ type VError =
168+ | MustNotBeEmpty
169+ | MustContainAt
170+ | MustContainPeriod
159171
160172 // ***** Base smart constructors *****
161173 // String must contain an '@' character
162- let atString ( x : string ) : Validation < VError list , AtString > =
174+ let atString ( x : string ) : Validation < VError list , AtString > =
163175 if String.contains '@' x then Success <| AtString x
164176 else Failure [ MustContainAt]
165177
166178 // String must contain an '.' character
167- let periodString ( x : string ) : Validation < VError list , PeriodString > =
179+ let periodString ( x : string ) : Validation < VError list , PeriodString > =
168180 if String.contains '.' x
169181 then Success <| PeriodString x
170182 else Failure [ MustContainPeriod]
171183
172184 // String must not be empty
173- let nonEmptyString ( x : string ) : Validation < VError list , NonEmptyString > =
174- if not <| String.IsNullOrEmpty x
185+ let nonEmptyString ( x : string ) : Validation < VError list , NonEmptyString > =
186+ if not <| String.IsNullOrEmpty x
175187 then Success <| NonEmptyString x
176188 else Failure [ MustNotBeEmpty]
177189
178190 // ***** Combining smart constructors *****
179- let email ( x : string ) : Validation < VError list , Email > =
191+ let email ( x : string ) : Validation < VError list , Email > =
180192 result ( Email x) <*
181193 nonEmptyString x <*
182194 atString x <*
0 commit comments