Comments (4)
I haven't had a chance to try this sample out myself, but my guess is that the typechecker is failing to unify the types of ok
and err
. If you try the same code, but with lambdas wrapping fun
and Result.ERR
, does it work?
from adt.
I revealed the type for the err
argument and indeed it was wrong, so I enforced the types for the arguments. Now mypy complains about the err
function, saying it should be Callable[[Result[E, B]], Result[E, B]]
from adt import adt, Case
from typing import Callable, Generic, TypeVar
A = TypeVar("A")
B = TypeVar("B")
E = TypeVar("E")
@adt
class Result(Generic[E, A]):
OK: Case[A]
ERR: Case[E]
def bind(self, f: Callable[[A], Result[E, B]]) -> Result[E, B]:
ok: Callable[[A], Result[E, B]] = f
err: Callable[[E], Result[E, B]] = Result.ERR
return self.match(ok=f, err=err)
from adt.
Does it work if you try to write something like this without the @adt
sugar? The only thing that I can think of at this point is that there is a genuine mypy bug or limitation.
from adt.
The following program type-checks with mypy 0.782 and python 3.8.5:
from dataclasses import dataclass
from typing import Generic, TypeVar, Callable, cast, Union, Mapping
E = TypeVar("E")
A = TypeVar("A")
B = TypeVar("B")
Fun = Callable[[A], B]
class Result(Generic[E, A]):
@staticmethod
def OK(value: A) -> 'Result[E, A]':
return Result(True, value)
@staticmethod
def ERR(value: E) -> 'Result[E, A]':
return Result(False, value)
def __init__(self, ok: bool, value: Union[E, A]):
self.ok = ok
self.value = value
def __repr__(self):
return f"OK {repr(self.value)}" if self.ok else f"ERR {repr(self.value)}"
def __str__(self):
return repr(self)
def match(self, ok: Fun[A, B], err: Fun[E, B]) -> B:
return ok(cast(A, self.value)) if self.ok else err(cast(E, self.value))
def bind(self, f: Fun[A, 'Result[E, B]']) -> 'Result[E, B]':
return self.match(ok=f, err=Result.ERR)
@dataclass
class User:
id: int
name: str
USERS: Mapping[int, User] = {
0: User(id=0, name="root")
}
def parse_user_id(s: str) -> Result[str, int]:
try:
return Result.OK(int(s))
except ValueError as e:
return Result.ERR(e.args[0])
def get_user(id: int) -> Result[str, User]:
if id not in USERS:
return Result.ERR('User not found')
else:
return Result.OK(USERS[id])
def get_user_from_str(s: str) -> Result[str, User]:
return parse_user_id(s).bind(get_user)
print(get_user_from_str("foo")) # ERR "invalid literal for int() with base 10: 'foo'"
print(get_user_from_str("10")) # ERR 'User not found'
print(get_user_from_str("0")) # OK User(id=0, name='root')
from adt.
Related Issues (20)
- Need a better README
- OO comparison: use visitor pattern as example, not just inheritance
- avoid dangerous designs & suggestions HOT 9
- Named fields HOT 1
- mypy plugin broken with mypy==0.730, works with 0.711 HOT 13
- Collaboration about pattern matching and adts HOT 1
- Publish source file to pypi HOT 1
- mypy plugin: match-function returning None does not type-check
- mypy plugin: Example for safe_integer in README does not type-check. HOT 1
- Migrate from CircleCI to GitHub Actions
- mypy plugin should be installable as an "extra"
- Implement hash function for ADTs HOT 1
- default option for pattern match
- PyCharm can't recognizes that `Case` is callable and etc. HOT 1
- Add support for matching using context managers. HOT 4
- Mixed-case case names not accepted by .match(), but README says they're fine
- mypy plugin causes TypeError: list object expected; got tuple w/ mypy==0.812
- sealed classes
- ADTs hashes are non unique
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from adt.