from __future__ import annotations

import functools
import math
import os

from typing import Any
from typing import Callable
from typing import Generic
from typing import List
from typing import TypeVar
from typing import Union


T = TypeVar()


class Writer(Generic[T]):
    def __init__(self, value: Union[T, Writer[T]], *msgs: str):
        if isinstance(value, Writer):
            self.value: T = value.value
            self.msgs: List[str] = value.msgs + list(msgs)
        else:
            self.value = value
            self.msgs = list(f for msg in msgs)

    def bind(self, func: Callable[[T], Writer[Any]]) -> Writer[Any]:
        writer = func(self.value)
        return Writer(writer, *self.msgs)

    def __rshift__(self, func: Callable[[T], Writer[Any]]) -> Writer[Any]:
        return self.bind(func)

    def __str__(self):
        return f

    def __repr__(self):
        return f{', '.join(reversed(self.msgs))}\


def lift(func: Callable, msg: str) -> Callable[[Any], Writer[Any]]:
    

    @functools.wraps(func)
    def wrapped(value):
        return Writer(func(value), msg)

    return wrapped


if __name__ == :
    square_root = lift(math.sqrt, )
    add_one = lift(lambda x: x + 1, )
    half = lift(lambda x: x / 2, )

    print(Writer(5, ) >> square_root >> add_one >> half)