Description
Consider:
@effect.option
def fn() -> Generator[Any, Any, List[str]]:
x: int = yield 42
y: str = yield f"{x} as a string"
z: List[str] = yield from Some([y, str(x)])
return z
Currently, unless each expression has the same type, you're stuck either being untyped or Any
-typed and manually typing each bound name. This is really unfortunate and not at all type-safe.
Chaining a bunch of transformations of values within a functor or monad is a very common use of Haskell do-expressions, Scala for-expressions, and presumably (although i have no first hand knowledge) F# computational expressions.
It's really nice to be able to chain these and rely on types to ensure the correctness of each step.
With the current approach, it doesn't seem possible to type the individual layers of unwrapping differently unless they all share the same contained type (for the contravariant type parameter). This is really limiting the usefulness, alas.
Context: I'm trying to introduce some good foundations and abstractions for correctness at my company, and I think Expression
could be a part of this based on its trajectory. However, the current limitations/ergonomics like this, combined with limitations in mypy
would make this a somewhat difficult sell, so I'm hoping there's a better approach or some ideas for improvement. Happy to assist where possible, but i'm definitely not an expert in python or python typing.