Option
Bases:
Type Option[T] represents an optional value.
Every Option is either:
Someand contains a valueNone, and does not.
This is a common type in Rust, and is used to represent values that may be absent.
In python, this is best tought of a an union type T | None,
but with additional methods to operate on the contained value in a functional style.
Option[T] and/or T | None types are very useful, as they have a number of uses:
- Initial values
- Union types
- Return value where None is returned on error
- Optional class fields
- Optional function arguments
The fact that T | None is a very common pattern in python,
but without a dedicated structure/handling, leads to:
- a lot of boilerplate code
- potential bugs (even with type checkers)
- less readable code (where does the None come from? is it expected?).
Option[T] instances are commonly paired with pattern matching.
This allow to query the presence of a value and take action, always accounting for the None case.
__bool__()
Prevent implicit Some|None value checking in boolean contexts.
Raises:
| Type | Description |
|---|---|
|
Always, to prevent implicit |
Example:
>>> import pyochain as pc
>>> x = pc.Some(42)
>>> bool(x)
Traceback (most recent call last):
...
TypeError: Option instances cannot be used in boolean contexts for implicit `Some|None` value checking. Use is_some() or is_none() instead.
__eq__(other)
Checks if this Option and other are equal.
A plain Python None is considered equal to a pyochain.NoneOption instance.
A plain value of type T is considered equal to a pyochain.Some[T] instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
|
The other object to compare with. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
|
See Also
Option.eqfor a type-safe, performant version that only acceptsOption[T]instances.
Example:
>>> import pyochain as pc
>>> pc.Some(42) == pc.Some(42)
True
>>> pc.Some(42) == pc.Some(21)
False
>>> pc.Some(42) == pc.NONE
False
>>> pc.NONE == pc.NONE
True
>>> pc.NONE == None
True
>>> pc.Some(42) == 42
True
__new__(value)
Creates an Option[V] from a value that may be None.
When calling Option(value), this method automatically redirects to:
- Some(value) if the value is not None
- NONE if the value is None
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
|
The value to convert into an |
required |
Returns:
| Type | Description |
|---|---|
|
Option[V]: |
Example:
>>> import pyochain as pc
>>> pc.Option(42)
Some(42)
>>> pc.Option(None)
NONE
and_(optb)
Returns NONE if the option is NONE, otherwise returns optb.
This is similar to and_then, except that the value is passed directly instead of through a closure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
optb
|
|
The option to return if the original option is |
required |
Returns:
Option[U]: NONE if the original option is NONE, otherwise optb.
Example:
>>> import pyochain as pc
>>> pc.Some(2).and_(pc.NONE)
NONE
>>> pc.NONE.and_(pc.Some("foo"))
NONE
>>> pc.Some(2).and_(pc.Some("foo"))
Some('foo')
>>> pc.NONE.and_(pc.NONE)
NONE
and_then(f, *args, **kwargs)
Calls a function if the option is Some, otherwise returns None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
|
The function to call with the |
required |
*args
|
|
Additional positional arguments to pass to f. |
()
|
**kwargs
|
|
Additional keyword arguments to pass to f. |
{}
|
Returns:
| Type | Description |
|---|---|
|
Option[R]: The result of the function if |
Example:
>>> import pyochain as pc
>>> def sq(x: int) -> Option[int]:
... return pc.Some(x * x)
>>> def nope(x: int) -> Option[int]:
... return pc.NONE
>>> pc.Some(2).and_then(sq).and_then(sq)
Some(16)
>>> pc.Some(2).and_then(sq).and_then(nope)
NONE
>>> pc.Some(2).and_then(nope).and_then(sq)
NONE
>>> pc.NONE.and_then(sq).and_then(sq)
NONE
and_then_star(func)
and_then_star(
func: Callable[[Any], Option[R]],
) -> Option[R]
and_then_star(
func: Callable[[T1, T2], Option[R]],
) -> Option[R]
and_then_star(
func: Callable[[T1, T2, T3], Option[R]],
) -> Option[R]
and_then_star(
func: Callable[[T1, T2, T3, T4], Option[R]],
) -> Option[R]
and_then_star(
func: Callable[[T1, T2, T3, T4, T5], Option[R]],
) -> Option[R]
and_then_star(
func: Callable[[T1, T2, T3, T4, T5, T6], Option[R]],
) -> Option[R]
and_then_star(
func: Callable[[T1, T2, T3, T4, T5, T6, T7], Option[R]],
) -> Option[R]
and_then_star(
func: Callable[
[T1, T2, T3, T4, T5, T6, T7, T8], Option[R]
],
) -> Option[R]
and_then_star(
func: Callable[
[T1, T2, T3, T4, T5, T6, T7, T8, T9], Option[R]
],
) -> Option[R]
and_then_star(
func: Callable[
[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], Option[R]
],
) -> Option[R]
Calls a function if the option is Some, unpacking the iterable into the function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
|
The function to call with the unpacked |
required |
Returns:
| Type | Description |
|---|---|
|
Option[R]: The result of the function if |
Example:
>>> import pyochain as pc
>>> pc.Some((2, 3)).and_then_star(lambda x, y: pc.Some(x + y))
Some(5)
>>> pc.NONE.and_then_star(lambda x, y: pc.Some(x + y))
NONE
eq(other)
Checks if two Option[T] instances are equal.
Note
This method behave similarly to __eq__, but only accepts Option[T] instances as argument.
This avoids runtime isinstance checks (we check for boolean is_some(), which is a simple function call), and is more type-safe.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
|
The other |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
|
Example:
>>> import pyochain as pc
>>> pc.Some(42).eq(pc.Some(42))
True
>>> pc.Some(42).eq(pc.Some(21))
False
>>> pc.Some(42).eq(pc.NONE)
False
>>> pc.NONE.eq(pc.NONE)
True
expect(msg)
Returns the contained Some value.
Raises an exception with a provided message if the value is None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
msg
|
|
The message to include in the exception if the result is |
required |
Returns:
| Name | Type | Description |
|---|---|---|
T |
|
The contained |
Raises:
| Type | Description |
|---|---|
|
If the result is |
Example:
>>> import pyochain as pc
>>> pc.Some("value").expect("fruits are healthy")
'value'
>>> pc.NONE.expect("fruits are healthy")
Traceback (most recent call last):
...
OptionUnwrapError: fruits are healthy (called `expect` on a `None`)
filter(predicate, *args, **kwargs)
Returns None if the option is None, otherwise calls predicate with the wrapped value.
This function works similar to Iter.filter in the sense that we only keep the value if it matches a predicate.
You can imagine the Option[T] being an iterator over one or zero elements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
predicate
|
|
The predicate to apply to the contained value. |
required |
*args
|
|
Additional positional arguments to pass to predicate. |
()
|
**kwargs
|
|
Additional keyword arguments to pass to predicate. |
{}
|
Returns:
| Type | Description |
|---|---|
|
Option[T]: |
Example:
>>> import pyochain as pc
>>>
>>> def is_even(n: int) -> bool:
... return n % 2 == 0
>>>
>>> pc.NONE.filter(is_even)
NONE
>>> pc.Some(3).filter(is_even)
NONE
>>> pc.Some(4).filter(is_even)
Some(4)
flatten()
Flattens a nested Option.
Converts an Option[Option[U]] into an Option[U] by removing one level of nesting.
Equivalent to Option.and_then(lambda x: x).
Returns:
| Type | Description |
|---|---|
|
Option[U]: The flattened option. |
Example:
>>> import pyochain as pc
>>> pc.Some(pc.Some(42)).flatten()
Some(42)
>>> pc.Some(pc.NONE).flatten()
NONE
>>> pc.NONE.flatten()
NONE
if_some(value)
staticmethod
Creates an Option[V] based on the truthiness of a value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
|
The value to evaluate. |
required |
Returns:
| Type | Description |
|---|---|
|
Option[V]: |
Example:
>>> import pyochain as pc
>>> pc.Option.if_some(42)
Some(42)
>>> pc.Option.if_some(0)
NONE
>>> pc.Option.if_some("hello")
Some('hello')
>>> pc.Option.if_some("")
NONE
if_true(value, *, predicate)
staticmethod
Creates an Option[V] based on a predicate condition on the provided value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
|
The value to wrap in |
required |
predicate
|
|
The condition to evaluate. |
required |
Returns:
| Type | Description |
|---|---|
|
Option[V]: |
Example:
>>> import pyochain as pc
>>> pc.Option.if_true(42, predicate=lambda x: x == 42)
Some(42)
>>> pc.Option.if_true(21, predicate=lambda x: x == 42)
NONE
>>> from pathlib import Path
>>> pc.Option.if_true(Path("README.md"), predicate=Path.exists).map(str)
Some('README.md')
>>> pc.Option.if_true(Path("README.md"), predicate=lambda p: p.exists()).map(str) # Same as above
Some('README.md')
inspect(f, *args, **kwargs)
Applies a function to the contained Some value, returning the original Option.
This allows side effects (logging, debugging, metrics, etc.) on the wrapped value without changing it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
|
Function to apply to the |
required |
*args
|
|
Additional positional arguments to pass to f. |
()
|
**kwargs
|
|
Additional keyword arguments to pass to f. |
{}
|
Returns:
| Type | Description |
|---|---|
|
Option[T]: The original option, unchanged. |
Example:
>>> import pyochain as pc
>>> seen: list[int] = []
>>> pc.Some(2).inspect(lambda x: seen.append(x))
Some(2)
>>> seen
[2]
>>> pc.NONE.inspect(lambda x: seen.append(x))
NONE
>>> seen
[2]
is_none()
Returns True if the option is a None value.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
|
Example:
>>> import pyochain as pc
>>> x: Option[int] = pc.Some(2)
>>> x.is_none()
False
>>> y: Option[int] = pc.NONE
>>> y.is_none()
True
is_none_or(func, *args, **kwargs)
Returns true if the option is a None or the value inside of it matches a predicate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
|
The predicate to apply to the contained value. |
required |
*args
|
|
Additional positional arguments to pass to func. |
()
|
**kwargs
|
|
Additional keyword arguments to pass to func. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
|
Example:
>>> import pyochain as pc
>>> pc.Some(2).is_none_or(lambda x: x > 1)
True
>>> pc.Some(0).is_none_or(lambda x: x > 1)
False
>>> pc.NONE.is_none_or(lambda x: x > 1)
True
>>> pc.Some("hello").is_none_or(lambda x: len(x) > 1)
True
is_some()
Returns True if the option is a Some value.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
|
Example:
>>> import pyochain as pc
>>> x: Option[int] = pc.Some(2)
>>> x.is_some()
True
>>> y: Option[int] = pc.NONE
>>> y.is_some()
False
is_some_and(predicate, *args, **kwargs)
Returns true if the option is a Some and the value inside of it matches a predicate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
predicate
|
|
The predicate to apply to the contained value. |
required |
*args
|
|
Additional positional arguments to pass to predicate. |
()
|
**kwargs
|
|
Additional keyword arguments to pass to predicate. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
|
Example:
>>> import pyochain as pc
>>> x = pc.Some(2)
>>> x.is_some_and(lambda x: x > 1)
True
>>> x = pc.Some(0)
>>> x.is_some_and(lambda x: x > 1)
False
>>> x = pc.NONE
>>> x.is_some_and(lambda x: x > 1)
False
>>> x = pc.Some("hello")
>>> x.is_some_and(lambda x: len(x) > 1)
True
iter()
Creates an Iter over the optional value.
- If the option is
Some(value), the iterator yieldsvalue. - If the option is
NONE, the iterator yields nothing.
Equivalent to Iter((self,)).
Returns:
| Type | Description |
|---|---|
|
Iter[T]: An iterator over the optional value. |
Example:
>>> import pyochain as pc
>>> pc.Some(42).iter().next()
Some(42)
>>> pc.NONE.iter().next()
NONE
map(f, *args, **kwargs)
Maps an Option[T] to Option[U].
Done by applying a function to a contained Some value,
leaving a None value untouched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
|
The function to apply to the |
required |
*args
|
|
Additional positional arguments to pass to f. |
()
|
**kwargs
|
|
Additional keyword arguments to pass to f. |
{}
|
Returns:
| Type | Description |
|---|---|
|
Option[R]: A new |
Example:
>>> import pyochain as pc
>>> pc.Some("Hello, World!").map(len)
Some(13)
>>> pc.NONE.map(len)
NONE
map_or(default, f, *args, **kwargs)
Returns the result of applying a function to the contained value if Some, otherwise returns the default value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
|
The default value to return if NONE. |
required |
f
|
|
The function to apply to the contained value. |
required |
*args
|
|
Additional positional arguments to pass to f. |
()
|
**kwargs
|
|
Additional keyword arguments to pass to f. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
R |
|
The result of f(self.unwrap()) if Some, otherwise default. |
Example:
>>> import pyochain as pc
>>> pc.Some(2).map_or(0, lambda x: x * 10)
20
>>> pc.NONE.map_or(0, lambda x: x * 10)
0
map_or_else(default, f)
Returns the result of applying a function to the contained value if Some, otherwise computes a default value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
|
A function returning the default value if NONE. |
required |
f
|
|
The function to apply to the contained value. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
R |
|
The result of f(self.unwrap()) if Some, otherwise default(). |
Example:
>>> import pyochain as pc
>>> pc.Some(2).map_or_else(lambda: 0, lambda x: x * 10)
20
>>> pc.NONE.map_or_else(lambda: 0, lambda x: x * 10)
0
map_star(func)
map_star(func: Callable[[Any], R]) -> Option[R]
map_star(func: Callable[[T1, T2], R]) -> Option[R]
map_star(func: Callable[[T1, T2, T3], R]) -> Option[R]
map_star(func: Callable[[T1, T2, T3, T4], R]) -> Option[R]
map_star(
func: Callable[[T1, T2, T3, T4, T5], R],
) -> Option[R]
map_star(
func: Callable[[T1, T2, T3, T4, T5, T6], R],
) -> Option[R]
map_star(
func: Callable[[T1, T2, T3, T4, T5, T6, T7], R],
) -> Option[R]
map_star(
func: Callable[[T1, T2, T3, T4, T5, T6, T7, T8], R],
) -> Option[R]
map_star(
func: Callable[[T1, T2, T3, T4, T5, T6, T7, T8, T9], R],
) -> Option[R]
map_star(
func: Callable[
[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], R
],
) -> Option[R]
Maps an Option[Iterable] to Option[U] by unpacking the iterable into the function.
Done by applying a function to a contained Some value,
leaving a None value untouched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
|
The function to apply to the unpacked |
required |
Returns:
| Type | Description |
|---|---|
|
Option[R]: A new |
Example:
>>> import pyochain as pc
>>> pc.Some((2, 3)).map_star(lambda x, y: x + y)
Some(5)
>>> pc.NONE.map_star(lambda x, y: x + y)
NONE
ne(other)
Checks if two Option[T] instances are not equal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
|
The other |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
|
Example:
>>> import pyochain as pc
>>> pc.Some(42).ne(pc.Some(21))
True
>>> pc.Some(42).ne(pc.Some(42))
False
>>> pc.Some(42).ne(pc.NONE)
True
>>> pc.NONE.ne(pc.NONE)
False
ok_or(err)
Converts the option to a Result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
err
|
|
The error value to use if the option is |
required |
Returns:
| Type | Description |
|---|---|
|
Result[T, E]: |
Example:
>>> import pyochain as pc
>>> pc.Some(1).ok_or('fail')
Ok(1)
>>> pc.NONE.ok_or('fail')
Err('fail')
ok_or_else(err)
Converts the option to a Result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
err
|
|
A function returning the error value if the option is NONE. |
required |
Returns:
| Type | Description |
|---|---|
|
Result[T, E]: Ok(v) if Some(v), otherwise Err(err()). |
Example:
>>> import pyochain as pc
>>> pc.Some(1).ok_or_else(lambda: 'fail')
Ok(1)
>>> pc.NONE.ok_or_else(lambda: 'fail')
Err('fail')
or_(optb)
Returns the option if it contains a value, otherwise returns optb.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
optb
|
|
The option to return if the original option is |
required |
Returns:
| Type | Description |
|---|---|
|
Option[T]: The original option if it is |
Example:
>>> import pyochain as pc
>>> pc.Some(2).or_(pc.NONE)
Some(2)
>>> pc.NONE.or_(pc.Some(100))
Some(100)
>>> pc.Some(2).or_(pc.Some(100))
Some(2)
>>> pc.NONE.or_(pc.NONE)
NONE
or_else(f)
Returns the Option[T] if it contains a value, otherwise calls a function and returns the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
|
The function to call if the option is |
required |
Returns:
| Type | Description |
|---|---|
|
Option[T]: The original |
Example:
>>> import pyochain as pc
>>> def nobody() -> Option[str]:
... return pc.NONE
>>> def vikings() -> Option[str]:
... return pc.Some("vikings")
>>> pc.Some("barbarians").or_else(vikings)
Some('barbarians')
>>> pc.NONE.or_else(vikings)
Some('vikings')
>>> pc.NONE.or_else(nobody)
NONE
reduce(other, func)
Reduces two options into one, using the provided function if both are Some.
If self is Some(s) and other is Some(o), this method returns Some(func(s, o)).
Otherwise, if only one of self and other is Some, that value is returned.
If both self and other are NONE, NONE is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
|
The second option. |
required |
func
|
|
The function to apply to the unwrapped values. |
required |
Returns:
| Type | Description |
|---|---|
|
Option[T]: The resulting option after reduction. |
Example:
>>> import pyochain as pc
>>> s12 = pc.Some(12)
>>> s17 = pc.Some(17)
>>>
>>> def add(a: int, b: int) -> int:
... return a + b
>>>
>>> s12.reduce(s17, add)
Some(29)
>>> s12.reduce(pc.NONE, add)
Some(12)
>>> pc.NONE.reduce(s17, add)
Some(17)
>>> pc.NONE.reduce(pc.NONE, add)
NONE
transpose()
Transposes an Option of a Result into a Result of an Option.
Some(Ok[T]) is mapped to Ok(Some[T]), Some(Err[E]) is mapped to Err[E], and NONE will be mapped to Ok(NONE).
Returns:
| Type | Description |
|---|---|
|
Result[Option[T], E]: The transposed result. |
Example:
>>> import pyochain as pc
>>> pc.Some(pc.Ok(5)).transpose()
Ok(Some(5))
>>> pc.NONE.transpose()
Ok(NONE)
>>> pc.Some(pc.Err("error")).transpose()
Err('error')
unwrap()
Returns the contained Some value.
Returns:
| Name | Type | Description |
|---|---|---|
T |
|
The contained |
Raises:
| Type | Description |
|---|---|
|
If the option is |
Example:
>>> import pyochain as pc
>>> pc.Some("car").unwrap()
'car'
>>> import pyochain as pc
>>> pc.NONE.unwrap()
Traceback (most recent call last):
...
OptionUnwrapError: called `unwrap` on a `None`
unwrap_or(default)
Returns the contained Some value or a provided default.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
|
The value to return if the result is |
required |
Returns:
| Name | Type | Description |
|---|---|---|
T |
|
The contained |
Example:
>>> import pyochain as pc
>>> pc.Some("car").unwrap_or("bike")
'car'
>>> pc.NONE.unwrap_or("bike")
'bike'
unwrap_or_else(f)
Returns the contained Some value or computes it from a function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
|
A function that returns a default value if the result is |
required |
Returns:
| Name | Type | Description |
|---|---|---|
T |
|
The contained |
Example:
>>> import pyochain as pc
>>> k = 10
>>> pc.Some(4).unwrap_or_else(lambda: 2 * k)
4
>>> pc.NONE.unwrap_or_else(lambda: 2 * k)
20
unzip()
Unzips an Option of a tuple into a tuple of Options.
If the option is Some((a, b)), this method returns (Some(a), Some(b)).
If the option is NONE, it returns (NONE, NONE).
Returns:
| Type | Description |
|---|---|
|
tuple[Option[T], Option[U]]: A tuple containing two options. |
Example:
>>> import pyochain as pc
>>> pc.Some((1, 'a')).unzip()
(Some(1), Some('a'))
>>> pc.NONE.unzip()
(NONE, NONE)
xor(optb)
Returns Some if exactly one of self, optb is Some, otherwise returns NONE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
optb
|
|
The other option to compare with. |
required |
Returns:
| Type | Description |
|---|---|
|
Option[T]: |
Example:
>>> import pyochain as pc
>>> pc.Some(2).xor(pc.NONE)
Some(2)
>>> pc.NONE.xor(pc.Some(2))
Some(2)
>>> pc.Some(2).xor(pc.Some(2))
NONE
>>> pc.NONE.xor(pc.NONE)
NONE
zip(other)
Returns an Option[tuple[T, U]] containing a tuple of the values if both options are Some, otherwise returns NONE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
|
The other option to zip with. |
required |
Returns:
| Type | Description |
|---|---|
|
Option[tuple[T, U]]: Some((self, other)) if both are Some, otherwise NONE. |
Example:
>>> import pyochain as pc
>>> pc.Some(1).zip(pc.Some('a'))
Some((1, 'a'))
>>> pc.Some(1).zip(pc.NONE)
NONE
>>> pc.NONE.zip(pc.Some('a'))
NONE
zip_with(other, f)
Zips self and another Option with function f.
If self is Some(s) and other is Some(o), this method returns Some(f(s, o)).
Otherwise, NONE is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
|
The second option. |
required |
f
|
|
The function to apply to the unwrapped values. |
required |
Returns:
| Type | Description |
|---|---|
|
Option[R]: The resulting option after applying the function. |
Example:
>>> from dataclasses import dataclass
>>> import pyochain as pc
>>>
>>> @dataclass
... class Point:
... x: float
... y: float
>>>
>>> x = pc.Some(17.5)
>>> y = pc.Some(42.7)
>>> x.zip_with(y, Point)
Some(Point(x=17.5, y=42.7))
>>> x.zip_with(pc.NONE, Point)
NONE
>>> pc.NONE.zip_with(y, Point)
NONE