Tutorial: make absence explicit

Tutorial: make absence explicit#

This tutorial builds a configuration lookup that can legitimately be missing. Use Option[T] when absence is enough information; use Result[T, E] when a caller needs an error explanation.

from expression import Nothing, Option, Some


def read_timeout(settings: dict[str, str]) -> Option[int]:
    raw_timeout = settings.get("TIMEOUT_SECONDS")
    if raw_timeout is None or not raw_timeout.isdigit():
        return Nothing
    return Some(int(raw_timeout))


assert read_timeout({"TIMEOUT_SECONDS": "30"}) == Some(30)
assert read_timeout({"TIMEOUT_SECONDS": "fast"}) is Nothing

Transform and validate without repeated None checks#

Use map for a transformation that always produces a plain value. Use bind for the next step when it can also be absent.

def positive(value: int) -> Option[int]:
    return Some(value) if value > 0 else Nothing


timeout = read_timeout({"TIMEOUT_SECONDS": "30"}).bind(positive).map(lambda value: value * 1_000)
missing_timeout = read_timeout({}).bind(positive)

assert timeout == Some(30_000)
assert missing_timeout is Nothing

At an application boundary, choose an intentional fallback or convert absence to a Result with a useful error. Do not unwrap an Option just to recreate unchecked None handling.