Python version of Rust Result Sum Type

2025-01-19

I try to implement a Python version of the Result<T, E> sum type in rust which can be used with match/case pattern matching.

The pattern matching with sub-patterns like case Err(e) could be implemented in Python with the __match_args__ dunder attribute. This is how Result[T, E], OK() and Err() defined:

import typing

T = typing.TypeVar('T')
E = typing.TypeVar('E')

class Result[T, E]:
    __match_args__ = ('_val',)
    def __init__(self, val):
        self._val = val

class Ok[T](Result[T, ...]):
    pass

class Err[E](Result[..., E]):
    pass

Below is the match/case block, note that if you have different types value to match(like different Error types), the guard(if statement behind the case pattern) must be used.

>>> def match(value):  
... match value:  
... case Ok(v): print(v)  
... case Err(e) if type(e) is str: print('str', e)  
... case Err(e) if type(e) is int: print('int', e)  
...  
>>> ok_result = Ok('Hello World')  
... e1 = Err('incorrect value')  
... e2 = Err(404)  
...  
>>> match(ok_result)  
Hello World  
>>> match(e1)  
str incorrect value  
>>> match(e2)  
int 404