Haskell Either Patterns
Haskell Either patterns are the shapes for working with a result that is either a failure or a success. They fold, chain, and split Either values without unwrapping them by hand.
Either folds both sides
The Left case gives a failure message. The Right case gives a success message.
main :: IO ()
main = do
print (either (\e -> "bad: " ++ e) (\n -> "good: " ++ show n) (Left "oops" :: Either String Int), either (\e -> "bad: " ++ e) (\n -> "good: " ++ show n) (Right 42 :: Either String Int))Bind stops at the first Left
A positive input doubles to 42. A negative input stops the chain with its failure message.
checkPos :: Int -> Either String Int
checkPos x = if x > 0 then Right x else Left "not positive"
doubleIt :: Int -> Either String Int
doubleIt x = Right (x * 2)
main :: IO ()
main = do
print (checkPos 21 >>= doubleIt, checkPos (-3) >>= doubleIt)Partition splits failures and successes
The list mixes two failures with two successes. partitionEithers groups each side together.
import Data.Either (partitionEithers)
main :: IO ()
main = do
print (partitionEithers [Right 1, Left "a", Right 2, Left "b"])Example
validateAge :: Int -> Either String Int
validateAge a = if a < 0 then Left "negative" else if a > 120 then Left "too big" else Right a
nextYear :: Int -> Either String Int
nextYear a = Right (a + 1)
main :: IO ()
main = do
print (validateAge 30 >>= nextYear, validateAge (-5) >>= nextYear)Key points
- Left: a Left value carries the failure side of an Either result.
- Right: a Right value carries the success side of an Either result.
- Either fold: either takes a failure function and a success function and returns one plain result.
- Bind: bind chains Either steps and stops at the first Left.
- Partition: partitionEithers splits a list of Either values into failures and successes.
In this example, the program defines a check for a valid age and a step that adds one year. A good age flows through both steps to 31. A bad age stops at the first step with its failure message.
Note
Either is a value, so a Left result never stops the program by itself.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Haskell Playground
Exercise
What does either do?