-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathPolymorphicEmail.hs
More file actions
72 lines (57 loc) · 1.92 KB
/
Copy pathPolymorphicEmail.hs
File metadata and controls
72 lines (57 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
-- Modification of the Email example that demonstrates converting
-- between Validation and Either using the 'either' isomorphism.
--
-- Validation accumulates all errors; Either short-circuits on first.
import Control.Lens ((#), (^.))
import Data.List (isInfixOf)
import Data.Validation
import Prelude hiding (either)
newtype Email = Email String deriving (Show)
data VError
= MustNotBeEmpty
| MustContainAt
| MustContainPeriod
deriving (Show)
-- ***** Base smart constructors *****
atString :: String -> Validation [VError] ()
atString x =
if "@" `isInfixOf` x
then _Success # ()
else _Failure # [MustContainAt]
periodString :: String -> Validation [VError] ()
periodString x =
if "." `isInfixOf` x
then _Success # ()
else _Failure # [MustContainPeriod]
nonEmptyString :: String -> Validation [VError] ()
nonEmptyString x =
if x /= []
then _Success # ()
else _Failure # [MustNotBeEmpty]
-- ***** Combining smart constructors *****
email :: String -> Validation [VError] Email
email x =
Email x
<$ nonEmptyString x
<* atString x
<* periodString x
-- ***** Example usage *****
success :: Validation [VError] Email
success = email "bob@gmail.com"
failureAt :: Validation [VError] Email
failureAt = email "bobgmail.com"
failurePeriod :: Validation [VError] Email
failurePeriod = email "bob@gmailcom"
failureAll :: Validation [VError] Email
failureAll = email ""
main :: IO ()
main = do
putStrLn "Collect all errors (Validation)"
putStrLn $ "email \"bob@gmail.com\": " ++ show success
putStrLn $ "email \"bobgmail.com\": " ++ show failureAt
putStrLn $ "email \"bob@gmailcom\": " ++ show failurePeriod
putStrLn $ "email \"\": " ++ show failureAll
putStrLn ""
putStrLn "Convert to Either (stop at first error via Either's Monad)"
putStrLn $ "email \"bob@gmail.com\": " ++ show (success ^. either)
putStrLn $ "email \"\": " ++ show (failureAll ^. either)