Guest User

Untitled

a guest
Jul 16th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.83 KB | None | 0 0
  1. {-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving #-}
  2.  
  3. import Data.Char
  4. import Control.Monad
  5. import Control.Monad.State
  6. type ErrorMessage = String
  7.  
  8. data User = User {
  9. name :: String
  10. , age :: Int
  11. , email :: String
  12. } deriving (Show)
  13.  
  14. data ValidatorState a = ValidatorState {
  15. subject :: a
  16. , errors :: [ErrorMessage]
  17. } deriving (Show)
  18.  
  19. newtype ValidatorMonad s a = ValidatorMonad (State (ValidatorState s) a) deriving (Monad, MonadState (ValidatorState s))
  20.  
  21. runValidator :: s -> ValidatorMonad s a -> Either [ErrorMessage] s
  22. runValidator s (ValidatorMonad m) =
  23. case errorMessages of
  24. [] -> Right s
  25. _ -> Left errorMessages
  26. where
  27. (_, vs) = runState m (ValidatorState s [])
  28. errorMessages = errors vs
  29.  
  30. getErrors :: ValidatorMonad a [ErrorMessage]
  31. getErrors = errors `liftM` get
  32.  
  33. setErrors :: [ErrorMessage] -> ValidatorMonad a ()
  34. setErrors es = get >>= \s -> put (s { errors = es })
  35.  
  36. modifyErrors :: ([ErrorMessage] -> [ErrorMessage]) -> ValidatorMonad a ()
  37. modifyErrors fn = setErrors . fn =<< getErrors
  38.  
  39.  
  40. class ModelValidator a where
  41. validateModel :: ValidatorMonad a ()
  42.  
  43. validate :: (a -> Bool) -> ErrorMessage -> ValidatorMonad a ()
  44. validate p errorMsg = do
  45. s <- subject `liftM` get
  46. when ((not . p) s) $ modifyErrors (errorMsg :)
  47.  
  48. rangeValidation fieldName fieldMethod start end = do
  49. let fn n = start < n && n < end
  50. validate (fn . fieldMethod) (fieldName ++ " must be between " ++ (show start) ++ " and " ++ (show end))
  51.  
  52. lowerCaseValidation fieldName fieldMethod = validate (isLowerCase . fieldMethod) (fieldName ++ " must be lowercase")
  53. where
  54. isLowerCase = all (\a -> (toLower a) == a)
  55.  
  56. instance ModelValidator User where
  57. validateModel = do
  58. lowerCaseValidation "Name" name
  59. rangeValidation "Age" age 0 18
  60.  
  61. sampleUser = User "Roman" 25 "romanandreg[at]gmail[dot]com"
  62.  
  63. -- runValidation sampleUser validateModel
Add Comment
Please, Sign In to add comment