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