ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Result & ResultE
    python/returns 2022. 9. 4. 21:37

    https://returns.readthedocs.io/en/latest/pages/result.html

    • scala Either 와 비슷한듯
    • error 를 Exception 으로 고정해 scala Try 처럼 사용해도 좋을 듯, ResultE[T] = Result[T, Exception]
    • Result.do 와 pipe 도 알아두자 (flow 대신에 Result.do 를 사용하자?)

     

    from typing import Callable
    
    from returns.pipeline import flow, pipe
    from returns.pointfree import bind
    from returns.result import Result, Success, Failure, ResultE
    
    x: ResultE[int] = Success(2)
    # x: Result[int, Exception] = Success(2)
    
    
    y: ResultE[int] = Success(3)
    # y: Result[int, Exception] = Success(3)
    
    
    def sum_of(x: int, y: int) -> int:
        return x + y
    
    
    # scala 에서의 for-comprehension ?
    z = Result.do(
        a + b  # sum_of(a, b) 로도 표현 가능
        for a in x
        for b in y
    )  # Success(5)
    
    
    #############################################################
    
    def f(x: int) -> ResultE[int]:
        return Success(x + 1)
    
    
    def g(x: int) -> ResultE[int]:
        return Success(x * 2)
    
    
    # 시작 값으로 computation (이것 보다는 아래의 Result.do 를 쓰는 것이 좋아 보임)
    flow(
        1,  # instance
        f,  # function
        bind(g)  # function
    )  # Success(4)
    
    # 위의 flow 를 Result.do 로 표현
    Result.do(
        y
        for x in f(1)
        for y in g(x)
    )  # Success(4)
    
    # function composition: 시작 값이 없이 function composition
    h: Callable[[int], ResultE[int]] = pipe(
        f,
        bind(g)
    )
    h(1)  # Success(4)
    
    
    #############################################################
    
    def recover(e: Exception) -> int:
        return 123
    
    
    def recover_with(e: Exception) -> ResultE[int]:
        return Success(456)
    
    
    def find_user(id: int) -> ResultE[int]:
        if id == 1:
            return Success(id + 100)
        else:
            return Failure(ValueError("invalid value"))
    
    
    find_user(1).alt(recover)  # 101
    find_user(2).alt(recover)  # 123
    
    find_user(1).lash(recover_with)  # 101
    find_user(2).lash(recover_with)  # 456

     

    Result + Maybe

    from returns.maybe import Maybe, Some
    from returns.pipeline import is_successful
    from returns.result import Success, ResultE, Failure, Result
    
    # maybe: Maybe[int] = Some(3)
    maybe: Maybe[int] = Maybe.empty
    # result: ResultE[int] = Success(1)
    result: ResultE[int] = Failure(ValueError)
    
    z: Maybe[int] | ResultE[int] = Result.do(
        x + y
        for x in maybe
        for y in result
    )
    
    # 방법 1
    v: int = z.value_or(9)
    print(v)
    
    # 방법 2
    if is_successful(z):
        v = z.unwrap()
        print(v)
    else:
        print('Error')
    
    # 방법 3
    match z:
        case Some(v) | Success(v):
            print(v)
        case Maybe.empty:
            print('Maybe Error')
        case Failure(e):
            print('Result Error')

     

    Result v.s Maybe

    from returns.converters import maybe_to_result, result_to_maybe
    from returns.maybe import Maybe, Some
    from returns.pipeline import is_successful
    from returns.result import Result, Success, ResultE
    
    x: ResultE[int] = Success(2)
    a: Maybe[int] = result_to_maybe(x)
    
    b: Maybe[int] = Some(3)
    y: Result[int, None] = maybe_to_result(b)
    
    is_successful(b)
    is_successful(y)

     

    @safe

    from returns.result import Success, Failure, safe
    
    
    # Will convert type to: Callable[[int], ResultE[float]]
    @safe  
    def divide(n: int, m: int) -> float:
        return n / m
    
    
    match divide(1, 0):
        case Success(10):
            print('Result is "10"')
        case Success(value):
            print(f'result={value}')
        case Failure(ZeroDivisionError()):
            print('"ZeroDivisionError" was raised')
        case Failure(_):
            print('The division was a failure')

    'python > returns' 카테고리의 다른 글

    IO & IOResult  (0) 2022.09.04
    Maybe  (0) 2022.09.04

    댓글

Designed by Tistory.