Skip to content

Instantly share code, notes, and snippets.

@pete-murphy
Last active July 18, 2020 10:02
Show Gist options
  • Save pete-murphy/d7707ab79e308fbf826465d35fa111d9 to your computer and use it in GitHub Desktop.
Save pete-murphy/d7707ab79e308fbf826465d35fa111d9 to your computer and use it in GitHub Desktop.
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
module ValidateForm where
import Data.Function ((&))
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Traversable
type Error = String
toRight :: Either a b -> (forall x. Either x (Maybe a))
toRight = \case
Left x -> Right (Just x)
Right _ -> Right Nothing
swapEither :: Either a b -> Either b a
swapEither = \case
Left x -> Right x
Right x -> Left x
validateForm ::
Ord k =>
Map k a ->
Map k (a -> Either Error b) ->
Either (Map k (Maybe Error)) (Map k b)
validateForm m mf =
Map.intersectionWith ($) mf m
& \validated -> sequenceA validated
& \case
Left _ ->
validated
& fmap toRight
& sequenceA
& swapEither
Right x -> Right x
isNonEmpty :: String -> Either Error String
isNonEmpty str = if null str then Left "Empty String" else Right str
validForm = Map.fromList [("name", "Joe"), ("occupation", "Plumber")]
partlyValidForm = Map.fromList [("name", "Joe"), ("occupation", "")]
invalidForm = Map.fromList [("name", ""), ("occupation", "")]
validators = Map.fromList [("name", isNonEmpty), ("occupation", isNonEmpty)]
main :: IO ()
main = do
print (validateForm validForm validators)
print (validateForm partlyValidForm validators)
print (validateForm invalidForm validators)
@pete-murphy
Copy link
Author

>>> main
Right (fromList [("name","Joe"),("occupation","Plumber")])
Left (fromList [("name",Nothing),("occupation",Just "Empty String")])
Left (fromList [("name",Just "Empty String"),("occupation",Just "Empty String")])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment