question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Typing issue with chained Result

See original GitHub issue

Take the following two functions as an example of two (or more) functions with unique failure modes (each function may fail in their own way)

def fraction(x: float ) -> Result[float, ZeroDivisionError]:
    try: return Success(1/x)
    except ZeroDivisionError as e: return Failure(e)

def log_of_arg_minus_one(x: float) -> Result[float, ValueError]:
    try: return Success(log(1-x))
    except ValueError as e: return Failure(e)

then a computation like fraction(x).bind(log_of_arg_minus_one) has potentially three different outcomes:

  1. the happy path where both functions return a Success, i.e. fraction(x) returns Success(y) where y is a float and log_of_arg_minus_one(y) returns Success(z) where z is also a float; example fraction(2).bind(log_of_arg_minus_one)
  2. the failure path of fraction , i.e. Failure(ZeroDivisionError); example: fraction(0).bind(log_of_arg_minus_one)
  3. the failure path of log_of_arg_minus_one, i.e. Failure(ValueError); example: fraction(1).bind(log_of_arg_minus_one)

Sadly this seems not to type correctly:

FailureCases = Union[ZeroDivisionError, ValueError]

z: Result[float, FailureCases] = fraction(1).bind(log_of_arg_minus_one)

# Argument 1 to "bind" of "Result" has incompatible type 
# "Callable[[float], Result[float, ValueError]]"; 
# expected "Callable[[float], Result[float, Union[ZeroDivisionError, ValueError]]]"

The following also doesn’t work:

z: Result[float, Exception] = fraction(1).bind(log_of_arg_minus_one)

# Argument 1 to "bind" of "Result" has incompatible type 
# "Callable[[float], Result[float, ValueError]]"; 
# expected "Callable[[float], Result[float, Exception]]"

I don’t know it this is an issue with bind (that might be fixable with a plugin) or just that Result[S, F] is not properly covariant with respect to F i.e. Result[X, A] is considered a subtype of Result[X, B] when A is a subtype of B

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:25 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
stereobuttercommented, Aug 30, 2019

@sobolevn I think a better name for the type aggregating bind might be chain (instead of unify)

1reaction
stereobuttercommented, Aug 12, 2019

Another general issue with the typing of Result that I originally mentioned in this issue (but that turned out be unrelated) is covariance. Consider:

z: Result[float, Exception] = Success(1).bind(fraction).bind(log_of_arg_minus_one)

As it currently is (regardless of the original or the proposed behavior) this doesn’t typecheck. I think it should?

Read more comments on GitHub >

github_iconTop Results From Across the Web

dependency injection - Typescript typings in chained calls
reduction of the issue to an injection problem. My issue. I'm trying to write some pattern that would allow an object to extend...
Read more >
A typed chain: exploring the limits of TypeScript
In my last post, I looked at how some of TypeScript's new features made it possible to correctly type Underscore.js's pluck method. In...
Read more >
Action Chaining - Apache Struts
The Chain Result is a result type that invokes an Action with its own Interceptor Stack and Result. This Interceptor allows an Action...
Read more >
Optional chaining, proper infer in type guard #34974 - GitHub
I have a similar issue with type guards. This compiles: type Person = { name: string; } ...
Read more >
Optional chaining (?.) - JavaScript - MDN Web Docs - Mozilla
This is an idiomatic pattern in JavaScript, but it gets verbose when the chain is long, and it's not safe. For example, if...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found