API reference¶
Maybe¶
-
cans.
Maybe
¶ A container which contains either one item, or none. Use
Just
andNothing
to express these two variants. When type annotating, only useMaybe
.>>> a: Maybe[int] = Just(5) >>> b: Maybe[str] = Nothing() ... >>> def parse(s: str) -> Maybe[int]: ... try: return Just(int(s)) ... except ValueError: return Nothing() ... >>> def first(m: list[T]) -> Maybe[T]: ... return Just(m[0]) if m else Nothing() ... >>> parse("42") Just(42) >>> first([]) Nothing()
Various methods are available (documented in
_MaybeMixin
) which you can use to operate on the value, without repeatedly unpacking it.>>> first(["-5", "6", ""]).flatmap(parse).map(abs) Just(5) >>> first([]).flatmap(parse).map(abs).unwrap_or("Nothing here...") "Nothing here..."
In Python 3.10+, you can use pattern matching to deconstruct a
Maybe
.>>> match first(["bob", "henry", "anita"]).map(str.title): ... case Just(x): ... print(f'Hello {x}!') ... case Nothing() ... print('Nobody here...') "Hello Bob!"
Maybe
also implements theSequence
API, meaning it acts kind of like a list with one or no items. Thus, it works nicely withitertools
!>>> from itertools import chain >>> list(chain.from_iterable(map(parse, "a4f59b"))) [4, 5, 9]
alias of Union[cans.Just[T], cans.Nothing[T]]
-
class
cans.
Just
(_value: T)[source]¶ The version of
Maybe
which contains a value.Example
>>> a: Maybe[int] = Just(-8) >>> a.map(abs).unwrap() 8
-
class
cans.
Nothing
[source]¶ The version of
Maybe
which does not contain a value.Example
>>> a: Maybe[int] = Nothing() >>> a.map(abs).unwrap_or("nope") "nope"
-
cans.
flatten
(m: Maybe[Maybe[T]]) → Maybe[T][source]¶ Flatten two nested maybes.
Example
>>> flatten(Just(Just(5))) Just(5) >>> flatten(Just(Nothing())) Nothing() >>> flatten(Nothing()) Nothing()
-
cans.
maybe_from_optional
(_v: Optional[T]) → Maybe[T][source]¶ Create a maybe container from the given value, which may be
None
. In that case, it’ll be an empty Maybe.Example
>>> maybe_from_optional(5) Just(5) >>> maybe_from_optional(None) Nothing()
-
class
cans.
_MaybeMixin
[source]¶ Bases:
Generic
[cans.T
],Sequence
[cans.T
]Collection of methods supported by both
Just
andNothing
.-
unwrap
() → T[source]¶ Unwrap the value in this container. If there is no value,
TypeError
is raised.Example
>>> Just(6).unwrap() 6 >>> Nothing().unwrap() Exception: TypeError()
Tip
Only use this if you’re absolutely sure that there is a value. If not, use
unwrap_or()
instead. Or, useexpect()
for a more descriptive message.
-
unwrap_or
(_default: V) → Union[T, V][source]¶ Unwrap the value in this container. If there is no value, return the given default.
Example
>>> Just(8).unwrap_or("foo") 8 >>> Nothing().unwrap_or("foo") "foo"
-
expect
(_msg: str) → T[source]¶ Unwrap the value in this container. If there is no value, raise an AssertionError with message
>>> Just(9).expect("What on earth?") 9 >>> Nothing().expect("What did you expect?") Exception: AssertionError("What did you expect?")
-
is_just
() → bool[source]¶ True if this Maybe contains a value
Example
>>> Just(2).is_just() True >>> Nothing().is_just() False
-
is_nothing
() → bool[source]¶ True if this Maybe does not contain a value
Example
>>> Just(2).is_nothing() False >>> Nothing().is_nothing() True
-
map
(_func: Callable[[T], U]) → Maybe[U][source]¶ Apply a function to the value inside the Maybe, without unwrapping it.
Example
>>> Just("hello").map(str.upper) Just("HELLO") >>> Nothing().map(abs) Nothing()
-
filter
(_func: Callable[[T], bool]) → Maybe[T][source]¶ Keep the value inside only if it satisfies the given predicate.
Example
>>> Just("9").filter(str.isdigit) Just("9") >>> Just("foo").filter(str.isdigit) Nothing() >>> Nothing().filter(str.isdigit) Nothing()
-
zip
(_other: Maybe[U]) → Maybe[Tuple[T, U]][source]¶ Combine two values in a tuple, if both are present.
Example
>>> Just(8).zip(Just(2)) Just((8, 2)) >>> Just(7).zip(Nothing()) Nothing() >>> Nothing().zip(Just(3)) Nothing() >>> Nothing().zip(Nothing()) Nothing()
-
flatmap
(_func: Callable[[T], Maybe[U]]) → Maybe[U][source]¶ Apply a function (which returns a maybe) to the value inside the
Maybe
. Then, flatten the result.Example
>>> def first(s) -> Maybe: ... try: ... return Just(s[0]) ... except LookupError: ... return Nothing() ... >>> Just([9, 4]).flatmap(first) Just(9) >>> Just([]).flatmap(first) Nothing() >>> Nothing().flatmap(first) Nothing()
-
as_optional
() → Optional[T][source]¶ Convert the value into an possibly-None value.
Example
>>> Just(6).as_optional() 6 >>> Nothing().as_optional() None
-
setdefault
(_v: V) → Maybe[Union[T, V]][source]¶ Set a value if one is not already present.
Example
>>> Just(6).setdefault(7) Just(6) >>> Nothing().setdefault(3) Just(3)
-
and_
(_other: Maybe[U]) → Maybe[Union[T, U]][source]¶ Perform a logical AND operation. Returns the first Nothing, or the last of the two values.
Tip
Available as the
and_()
method as well as the&
operator.Example
>>> Just(5) & Just(9) Just(9) >>> Just(5).and_(Just(9)) Just(9) >>> Just(9) & Nothing() Nothing() >>> Nothing() & Just(8) Nothing()
-
__and__
(_other: Maybe[U]) → Maybe[Union[T, U]]¶ Perform a logical AND operation. Returns the first Nothing, or the last of the two values.
Tip
Available as the
and_()
method as well as the&
operator.Example
>>> Just(5) & Just(9) Just(9) >>> Just(5).and_(Just(9)) Just(9) >>> Just(9) & Nothing() Nothing() >>> Nothing() & Just(8) Nothing()
-
or_
(_other: Maybe[U]) → Maybe[Union[T, U]][source]¶ Perform a logical OR operation. Return the first Just, or the last of the two values.
Tip
Available as the
or_()
method as well as the|
operator.Example
>>> Just(5) | Just(9) Just(5) >>> Just(5).or_(Just(9)) Just(5) >>> Just(9) | Nothing() Just(9) >>> Nothing() | Just(8) Just(8) >>> Nothing() | Nothing() Nothing()
-
__or__
(_other: Maybe[U]) → Maybe[Union[T, U]]¶ Perform a logical OR operation. Return the first Just, or the last of the two values.
Tip
Available as the
or_()
method as well as the|
operator.Example
>>> Just(5) | Just(9) Just(5) >>> Just(5).or_(Just(9)) Just(5) >>> Just(9) | Nothing() Just(9) >>> Nothing() | Just(8) Just(8) >>> Nothing() | Nothing() Nothing()
-
__iter__
() → Iterator[T][source]¶ Iterate over the contained item, if present.
Example
>>> list(Just(5)) [5] >>> list(Nothing()) []
-
__contains__
(_v: object) → bool[source]¶ Check if the item is contained in this object.
Example
>>> 5 in Just(5) True >>> 4 in Just(8) False >>> 1 in Nothing() False
-
__len__
() → int[source]¶ The number of items contained (0 or 1)
Example
>>> len(Just(5)) 1 >>> len(Nothing()) 0
-
__getitem__
(_i: int) → T[source]¶ -
__getitem__
(_i: slice) → Maybe[T] Get the item from this container by index. Part of the
Sequence
API.Behaves similarly to a list of one or zero items.
Example
>>> Just(6)[0] 6 >>> Just(8)[8] Exception: IndexError >>> Nothing()[0] Exception: IndexError ... >>> Just(6)[:] Just(6) >>> Just(2)[:9:4] Just(2) >>> Just(7)[2:] Nothing() >>> Nothing()[:] Nothing() >>> Nothing()[2:9:5] Nothing()
-