🎓 A1Learner
🔍
0 of 54 lessons completed

Haskell Safe Results

Safe results are return values that show whether a step succeeded or failed. Maybe and Either are two safe results that carry different amounts of detail.

Maybe fits a missing value with no reason

The findAge function returns Nothing for an unknown name. The caller learns only that no age was found.

findAge :: String -> Maybe Int
findAge "Ana" = Just 31
findAge _ = Nothing

main :: IO ()
main = print (findAge "Ben")

Either keeps the reason

The validateAge function returns Left with a message for an age below 18. The message tells the caller why the check failed.

validateAge :: Int -> Either String Int
validateAge age
  | age < 18 = Left "Too young"
  | otherwise = Right age

main :: IO ()
main = print (validateAge 15)

A second checked step divides safely

The dividePoints function returns Left when the game count is 0. For a game count of 4, it returns the points per game inside Right.

dividePoints :: Int -> Int -> Either String Int
dividePoints _ 0 = Left "Games cannot be zero"
dividePoints points games = Right (div points games)

main :: IO ()
main = print (dividePoints 100 4)

Example

validateAge :: Int -> Either String Int
validateAge age
  | age < 18 = Left "Too young"
  | otherwise = Right age

dividePoints :: Int -> Int -> Either String Int
dividePoints _ 0 = Left "Games cannot be zero"
dividePoints points games = Right (div points games)

playerAverage :: Int -> Int -> Int -> Either String Int
playerAverage age points games =
  case validateAge age of
    Left msg -> Left msg
    Right _ ->
      case dividePoints points games of
        Left msg -> Left msg
        Right avg -> Right avg

main :: IO ()
main = print (playerAverage 20 90 3)

Key points

  • Maybe choice: use Maybe when the caller only needs to know that a value is missing.
  • Either choice: use Either when the caller needs to know why a step failed.
  • Checked step: a step that returns an Either value instead of an unchecked result.
  • Pipeline: a chain of checked steps where one result feeds the next step.
  • Case combining: a case reads each Either result and decides the next step.

In this example, playerAverage first runs validateAge on 20 and gets a Right value. It then runs dividePoints on 90 points and 3 games, which returns Right 30. The main action prints that final Right value.

Note

Haskell code in this style reports failure by returning a value, not by throwing an error.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

When should a function choose Either instead of Maybe?