Bind method doesn't propagate error types correctly in chained operations
Opened this issue · 0 comments
edodo1337 commented
The current implementation of the bind method in the Result
class does not properly propagate or merge error types when chaining operations. For example:
@dataclass
class Order:
amount: float
product: str
def verify_amount(order: Order) -> Result[Order, ValueError]:
if order.amount < 0:
return Error(ValueError("Amount cannot be negative"))
return Ok(order)
def verify_product(order: Order) -> Result[Order, ValueError]:
if order.product not in ["Apple", "Banana"]:
return Error(ValueError("Product not found"))
return Ok(order)
def order_amount_with_commission(order: Order) -> Result[float, ValueError | KeyError]:
return Ok(order.amount * 1.1)
order = Order(amount=-100, product="Apple1")
result = (
Ok(order)
.bind(verify_amount)
.bind(verify_product)
.bind(order_amount_with_commission)
)
The expected type of result should be:
Result[float, ValueError | KeyError]
However, the actual inferred type is:
Result[float, Any]
I found that a small change in the bind method's type signature partially solves the issue by propagating and merging error types more accurately. However, Any
still remains in the inferred Result
type:
def bind(self, mapper: Callable[[_TSourceOut], Result[_TResult, _TError | _TOther]]) -> Result[_TResult, _TError | _TOther]:
Now type inferred as Result[float, ValueError | KeyError | Any]