Skip to content

Instantly share code, notes, and snippets.

@notgiorgi
Last active May 5, 2017 08:29
Show Gist options
  • Save notgiorgi/ff6cea65d87106ffe49062956a979c74 to your computer and use it in GitHub Desktop.
Save notgiorgi/ff6cea65d87106ffe49062956a979c74 to your computer and use it in GitHub Desktop.
applicative validation

haskell (its kind of pseudo-code)

data Person = Person String String

liftA2 Person (Just "George") (Just "Martin")
-- is same as
Person <$> (Just "George") <*> (Just "Martin")
-- evaluation steps:
Just (\surname -> Person "George" surname) <*> (Just "Martin")
Just (Person "George" "Martin")

-- analog
liftA2 Person (Just "George") Nothing
-- is same as
Person <$> (Just "George") <*> Nothing
-- evaluation steps:
Just (\surname -> Person "George" surname) <*> Nothing
Nothing

-- in real word

-- we have validators:
checkName name
  | length name < 2 = Nothing
  | otherwise = Just name

checkSurname sname
  | length sname < 2 = Nothing
  | sname == "Doe" = Nothing
  | otherwise = Just sname
  
mkPerson nameFromSomeUserInput surnameFromSomeUserInput =
  Person
  <$> checkName nameFromSomeUserInput -- this returns `Just "<name>"` or `Nothing` like in previus example
  <$> checkSurname surnameFromSomeUserInput
  
-- In case we want to display errors we could use
-- Either type
checkName name
  | length name < 2 = Left "name is too short"
  | otherwise = Right name
  
-- and etc...

-- If we use
-- Monoid err => Either err a
-- then we can even accumulate errors to display them later
-- we would define `<*>` as follows
(<*>) (Left err1) (Left err2) = Left (err1 <> err2)

js

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