dry-python / dry-python/returns
Standard library map on bound function
- Dominant language
- Python
- Stars
- 4.4k
- Forks
- 155
- Avg merge
- 2h 27m
- Merged PRs (30d)
- 22
Description
# Bug report
Mypy does not appear to correctly handle the standard library `map` function over an iterable of containers that returns an iterable of containers, when the function being mapped over the data has had `returns.pointfree.bind` applied to it. The same code when used without `map` (by explicit use of a for-loop) or a `bind` (by explicitly handling a container input) will not result in an error.
## What's wrong
### Code to reproduce issue
```python
from typing import Iterable
from returns.pointfree import bind
from returns.result import ResultE
from returns.result import safe
@safe
def f(x: int) -> str:
return str(x)
@safe
def g(x: str) -> int:
return int(x)
def h(xs: Iterable[ResultE[int]]) -> None:
for x in xs:
print(x.unwrap())
if __name__ == "__main__":
h(map(bind(g), map(f, range(3))))
```
### Mypy output
```bash
$ mypy test.py
test.py:24:11: error: Argument 1 to "map" has incompatible type "Kinded[Callable[[KindN[Result[Any, Any], str, Exception, NoReturn]], KindN[Result[Any, Any], int, Exception, NoReturn]]]"; expected "Callable[[Result[str, Exception]], Res
ult[int, Exception]]" [arg-type]
test.py:24:11: note: "Kinded[Callable[[KindN[Result[Any, Any], str, Exception, NoReturn]], KindN[Result[Any, Any], int, Exception, NoReturn]]].__call__" has type "Callable[[KindN[Result[Any, Any], str, Exception, NoReturn]], KindN[Resul
t[Any, Any], int, Exception, NoReturn]]"
Found 1 error in 1 file (checked 1 source file)
```
### Python output
```bash
$ python test.py
0
1
2
```
## How it should be
When the `h` function is replaced with a for-loop in `__main__` no issues are reported by Mypy and the code executes correctly:
```python
if __name__ == "__main__":
for x in map(f, range(3)):
print(x.bind(g).unwrap())
```
Can also fix the issue by swapping out the `g` function:
```python
def g(x: ResultE[str]) -> ResultE[int]:
return x.map(int)
if __name__ == "__main__":
h(map(g, map(f, range(3))))
```
## System information
- `python` version: 3.8.6
- `returns` version: 0.15.0
- `mypy` version: 0.800 (also observed in v0.782 due to `classess` library dependency)
Contributor guide
Assessment
This issue has not been assessed yet.