# Path: oslash/util/basic.py
# def indent(level, size=2):
# 
# Path: oslash/typing/functor.py
# class Functor(Protocol[TSource]):
#     """The Functor class is used for types that can be mapped over.
# 
#     Instances of Functor should satisfy the following laws:
# 
#     Haskell:
#     fmap id  ==  id
#     fmap (f . g)  ==  fmap f . fmap g
# 
#     Python:
#     x.map(id) == id(x)
#     x.map(compose(f, g)) == x.map(g).map(f)
# 
#     The instances of Functor for lists, Maybe and IO satisfy these laws.
#     """
# 
#     @abstractmethod
#     def map(self, fn: Callable[[TSource], TResult]) -> 'Functor[TResult]':
#         """Map a function over wrapped values.
# 
#         Map knows how to apply functions to values that are wrapped in
#         a context.
#         """
#         raise NotImplementedError
# 
#     # def __rmod__(self, fn):
#     #     """Infix version of map.
# 
#     #     Haskell: <$>
# 
#     #     Example:
#     #     >>> (lambda x: x+2) % Just(40)
#     #     42
# 
#     #     Returns a new Functor.
#     #     """
#     #     return self.map(fn)
# 
# Path: oslash/typing/monad.py
# class Monad(Protocol[TSource]):
#     """Monad protocol"""
# 
#     @abstractmethod
#     def bind(self, fn: Callable[[TSource], 'Monad[TResult]']) -> 'Monad[TResult]':
#         """Monad bind method.
# 
#         Python: bind(self: Monad[A], func: Callable[[A], Monad[B]]) -> Monad[B]
#         Haskell: (>>=) :: m a -> (a -> m b) -> m b
# 
#         This is the mother of all methods. It's hard to describe what it
#         does, because it can be used for pretty much anything:
# 
#         * Transformation, for projecting Monadic values and functions.
#         * Composition, for composing monadic functions.
#         * Chaining, for chaining of functions as a monadic value.
#         * Combining, for combining monadic values.
#         * Sequencing, of Monadic functions.
#         * Flattening, of nested Monadic values.
#         * Variable substitution, assign values to variables.
# 
#         The Monad doesn’t specify what is happening, only that whatever
#         is happening satisfies the laws of associativity and identity.
# 
#         Returns a new Monad.
#         """
#         raise NotImplementedError
# 
#     @classmethod
#     @abstractmethod
#     def unit(value: TSource) -> 'Monad[TSource]':
#         """Wrap a value in a default context.
# 
#         Haskell: return :: a -> m a .
# 
#         Inject a value into the monadic type. Since return is a reserved
#         word in Python, we align with Scala and use the name unit
#         instead.
#         """
#         raise NotImplementedError
# 
#     #def lift(self, func: Callable) -> Monad[B]:
#     #    """Map function over monadic value.
#     #
#     #    Takes a function and a monadic value and maps the function over the
#     #    monadic value
#     #
#     #    Haskell: liftM :: (Monad m) => (a -> b) -> m a -> m b
#     #
#     #    This is really the same function as Functor.fmap, but is instead
#     #    implemented using bind, and does not rely on us inheriting from
#     #    Functor.
#     #    """
#     #
#     #    return self.bind(lambda x: Monad.unit(func(x)))
# 
# 
#     #def join(self):
#     #    """join :: Monad m => m (m a) -> m a
#     #
#     #    The join function is the conventional monad join operator. It is
#     #    used to remove one level of monadic structure, projecting its
#     #    bound argument into the outer level."""
# 
#     #    return self.bind(identity)


from typing import Callable, Tuple, Any, TypeVar, Generic
from .util import Unit
from .typing import Functor
from .typing import Monad
        r"""m >>= k = State $ \s -> let (a, s') = runState m s
        in runState (k a) s'
        """

        def _(result: Any, state: Any) -> Tuple[Any, Any]:
            return fn(result).run(state)

        return State(lambda state: _(*self.run(state)))

    @classmethod
    def get(cls) -> "State[TState, TState]":
        r"""get = state $ \s -> (s, s)"""
        return State(lambda state: (state, state))

    @classmethod
    def put(cls, new_state: TState) -> "State[Tuple, TState]":
        r"""put newState = state $ \s -> ((), newState)"""
        return State(lambda state: (Unit, new_state))

    def run(self, state: TState) -> Tuple[TSource, TState]:
        """Return wrapped state computation.

        This is the inverse of unit and returns the wrapped function.
        """
        return self._fn(state)

    def __call__(self, state: Any) -> Tuple:
        return self.run(state)



# Path: oslash/util/basic.py
# def indent(level, size=2):
# 
# Path: oslash/typing/functor.py
# class Functor(Protocol[TSource]):
#     """The Functor class is used for types that can be mapped over.
# 
#     Instances of Functor should satisfy the following laws:
# 
#     Haskell:
#     fmap id  ==  id
#     fmap (f . g)  ==  fmap f . fmap g
# 
#     Python:
#     x.map(id) == id(x)
#     x.map(compose(f, g)) == x.map(g).map(f)
# 
#     The instances of Functor for lists, Maybe and IO satisfy these laws.
#     """
# 
#     @abstractmethod
#     def map(self, fn: Callable[[TSource], TResult]) -> 'Functor[TResult]':
#         """Map a function over wrapped values.
# 
#         Map knows how to apply functions to values that are wrapped in
#         a context.
#         """
#         raise NotImplementedError
# 
#     # def __rmod__(self, fn):
#     #     """Infix version of map.
# 
#     #     Haskell: <$>
# 
#     #     Example:
#     #     >>> (lambda x: x+2) % Just(40)
#     #     42
# 
#     #     Returns a new Functor.
#     #     """
#     #     return self.map(fn)
# 
# Path: oslash/typing/monad.py
# class Monad(Protocol[TSource]):
#     """Monad protocol"""
# 
#     @abstractmethod
#     def bind(self, fn: Callable[[TSource], 'Monad[TResult]']) -> 'Monad[TResult]':
#         """Monad bind method.
# 
#         Python: bind(self: Monad[A], func: Callable[[A], Monad[B]]) -> Monad[B]
#         Haskell: (>>=) :: m a -> (a -> m b) -> m b
# 
#         This is the mother of all methods. It's hard to describe what it
#         does, because it can be used for pretty much anything:
# 
#         * Transformation, for projecting Monadic values and functions.
#         * Composition, for composing monadic functions.
#         * Chaining, for chaining of functions as a monadic value.
#         * Combining, for combining monadic values.
#         * Sequencing, of Monadic functions.
#         * Flattening, of nested Monadic values.
#         * Variable substitution, assign values to variables.
# 
#         The Monad doesn’t specify what is happening, only that whatever
#         is happening satisfies the laws of associativity and identity.
# 
#         Returns a new Monad.
#         """
#         raise NotImplementedError
# 
#     @classmethod
#     @abstractmethod
#     def unit(value: TSource) -> 'Monad[TSource]':
#         """Wrap a value in a default context.
# 
#         Haskell: return :: a -> m a .
# 
#         Inject a value into the monadic type. Since return is a reserved
#         word in Python, we align with Scala and use the name unit
#         instead.
#         """
#         raise NotImplementedError
# 
#     #def lift(self, func: Callable) -> Monad[B]:
#     #    """Map function over monadic value.
#     #
#     #    Takes a function and a monadic value and maps the function over the
#     #    monadic value
#     #
#     #    Haskell: liftM :: (Monad m) => (a -> b) -> m a -> m b
#     #
#     #    This is really the same function as Functor.fmap, but is instead
#     #    implemented using bind, and does not rely on us inheriting from
#     #    Functor.
#     #    """
#     #
#     #    return self.bind(lambda x: Monad.unit(func(x)))
# 
# 
#     #def join(self):
#     #    """join :: Monad m => m (m a) -> m a
#     #
#     #    The join function is the conventional monad join operator. It is
#     #    used to remove one level of monadic structure, projecting its
#     #    bound argument into the outer level."""
# 
#     #    return self.bind(identity)


# Path: oslash/state.py
from typing import Callable, Tuple, Any, TypeVar, Generic
from .util import Unit
from .typing import Functor
from .typing import Monad

        r"""m >>= k = State $ \s -> let (a, s') = runState m s
        in runState (k a) s'
        """

        def _(result: Any, state: Any) -> Tuple[Any, Any]:
            return fn(result).run(state)

        return State(lambda state: _(*self.run(state)))

    @classmethod
    def get(cls) -> "State[TState, TState]":
        r"""get = state $ \s -> (s, s)"""
        return State(lambda state: (state, state))

    @classmethod
    def put(cls, new_state: TState) -> "State[Tuple, TState]":
        r"""put newState = state $ \s -> ((), newState)"""
        return State(lambda state: (Unit, new_state))

    def run(self, state: TState) -> Tuple[TSource, TState]:
        """Return wrapped state computation.

        This is the inverse of unit and returns the wrapped function.
        """
        return self._fn(state)

    def __call__(self, state: Any) -> Tuple:
        return self.run(state)



assert issubclass(State, Functor)