returns
returns copied to clipboard
support for Python's container interfaces
related: #874, #592
Python has a rich set of container interfaces, like __iter__
, __len__
, __contains__
, and others.
could we treat Maybe
as a collection (i.e. one containing 0 or 1 items)? It may seem weird, but it has precedent. In Rust, Option
implements iteration and other collection-like traits as well.
...but why?
- It'd be consistent to make the containers in
returns
compatible with the Python builtin containers. You get expected behavior (empty containers are falsey), and it fits in the universe of iterables anditertools
. - It can enable some nice use-cases (Some more contrived than others, I must admit 😉 )
>>> def parse_int(s: str) -> Maybe[int]: ...
>>> # easier flattening with `__iter__`
>>> list(chain.from_iterable(map(parse_int, 'a45bf'))))
[4, 5]
>>> # truthiness with `__bool__`
>>> if parse_int(mystr):
... print('a valid int!')
>>> # checking contents with `__contains__`
>>> if 5 in parse_int(mystr):
... print('number five detected!')
>>> # not strictly collection-related but still nice: __or__ and __and__
>>> Some(5) & Some(9)
Some(9)
>>> Some(9) & Nothing
Nothing
>>> Nothing & Some(8)
Nothing
>>> Some(5) | Some(9)
Some(5)
>>> Some(9) | Nothing
Some(9)
>>> Nothing | Some(8)
Some(8)
>>> Nothing | Nothing
Nothing
>>> # if you want to go crazy: use __getitem__ to implement Sequence
>>> Some(6)[0]
6
>>> Some(8)[8]
Exception: IndexError
>>> Nothing[0]
Exception: IndexError
...
>>> Some(6)[:]
Some(6)
>>> Some(2)[:9:4]
Some(2)
>>> Some(7)[2:]
Nothing
>>> Nothing[:]
Nothing
>>> Nothing[2:9:5]
Nothing
I'm sure you have some opinion on this, but couldn't find it in the issues so far... 👀
Good idea! But, we are blocked right now because of #392 I don't know which methods it will require.
Interesting!
Note though that once you abuse one of the container interfaces (iter, getitem, contains, etc.), the others are pretty much off the table as well (otherwise you get a really wonky API)
I'm eager to see what the outcome is 👀