git.iko.soy/typeable/validationt
on ea290fa help sign in
75 lines 2.6 kB history raw
1![Travis CI Badge](https://img.shields.io/travis/typeable/validationt)
3# ValidationT
5A very small validation data library.
7## Usage
9Suppose you want to validate some data from the user. Say, that the password adheres to some rules.
11You might do something like this:
13```haskell
14validatePassword :: Monad m => String -> ValidationT [String] m ()
15validatePassword password = do
16 vLength password
17 vAlpha password
18 vNum password
19 where
20 vLength p = when (length p < 8)
21 $ vWarning ["The password should be at least 8 characters long."]
22 vAlpha p = unless (any isAlpha p)
23 $ vWarning ["The password should contain at least one alphabetic character."]
24 vNum p = unless (any isDigit p)
25 $ vWarning ["The password should contain at least one numeric character."]
26```
28`ValidationT e m a` essentially just gathers the errors thrown by `vWarning`.
30```haskell
31vWarning :: (Monad m, Monoid e) => e -> ValidationT e m ()
32```
34`vWarning` `mappend`s the given `e` to the already collected errors. This is why the warnings are contained inside a list.
36There is also `vError`. The only difference between `vWarning` and `vError` is that `vError` stops further execution (and further collection of errors and warnings).
38You would use the validation like this:
40```haskell
41main :: IO ()
42main = do
43 password <- getLine
44 result <- runValidationTEither . validatePassword $ password
45 putStrLn $ case result of
46 Left errs -> unlines err
47 Right () -> "You are fine."
48```
50You could, of course, do more complicated things like use `vWarningL` and `vErrorL` to add an error to a `mempty` structure, which gets `mappend`ed with other errors.
52The library comes with a `MonoidMap` `newtype` wrapper around `Map`, which `mappend`s the values themselves on conflict. This can be useful if you have a multiple points of failure and you want to distinguich between them -- validating a username and a password for example:
54```haskell
55data Piece
56 = Password
57 | UserName
58 deriving (Eq, Show, Ord)
60validatePassword :: Monad m => String -> ValidationT (MonoidMap Piece [String]) m ()
61validatePassword password = do
62 vLength password
63 vAlpha password
64 vNum password
65 where
66 warning = mmSingleton UserName
67 vLength p = when (length p < 8)
68 $ warning ["The password should be at least 8 characters long."]
69 vAlpha p = unless (any isAlpha p)
70 $ warning ["The password should contain at least one alphabetic character."]
71 vNum p = unless (any isDigit p)
72 $ warning ["The password should contain at least one numeric character."]
73```
75(`mmSingleton` is a covenience initializer for `MonoidMap`.)