# Path: oslash/cont.py
# class Cont(Generic[T, TResult]):
#     """The Continuation Monad.
# 
#     The Continuation monad represents suspended computations in continuation-
#     passing style (CPS).
#     """
# 
#     def __init__(self, comp: Callable[[TCont], TResult]) -> None:
#         """Cont constructor.
# 
#         Keyword arguments:
#         cont -- A callable
#         """
#         self._comp = comp
# 
#     @classmethod
#     def unit(cls, value: T) -> 'Cont[T, TResult]':
#         """Create new continuation.
# 
#         Haskell: a -> Cont a
#         """
#         fn: Callable[[TCont], TResult] = lambda cont: cont(value)
#         return Cont(fn)
# 
#     def map(self, fn: Callable[[T], T2]) -> 'Cont[T2, TResult]':
#         r"""Map a function over a continuation.
# 
#         Haskell: fmap f m = Cont $ \c -> runCont m (c . f)
#         """
#         def comp(cont: Callable[[T2], TResult]) -> TResult:
#             return self.run(compose(cont, fn))
#         return Cont(comp)
# 
#     def bind(self, fn: Callable[[T], 'Cont[T2, TResult]']) -> 'Cont[T2, TResult]':
#         r"""Chain continuation passing functions.
# 
#         Haskell: m >>= k = Cont $ \c -> runCont m $ \a -> runCont (k a) c
#         """
#         return Cont(lambda cont: self.run(lambda a: fn(a).run(cont)))
# 
#     @staticmethod
#     def call_cc(fn: Callable) -> 'Cont':
#         r"""call-with-current-continuation.
# 
#         Haskell: callCC f = Cont $ \c -> runCont (f (\a -> Cont $ \_ -> c a )) c
#         """
#         return Cont(lambda c: fn(lambda a: Cont(lambda _: c(a))).run(c))
# 
#     def run(self, cont: Callable[[T], TResult]) -> TResult:
#         return self._comp(cont)
# 
#     def __or__(self, func):
#         """Use | as operator for bind.
# 
#         Provide the | operator instead of the Haskell >>= operator
#         """
#         return self.bind(func)
# 
#     def __call__(self, comp: Callable[[T], TResult]) -> TResult:
#         return self.run(comp)
# 
#     def __eq__(self, other) -> bool:
#         return self(identity) == other(identity)
# 
# Path: oslash/util/fn.py
# A = TypeVar("A")
# B = TypeVar("B")
# C = TypeVar("C")
# D = TypeVar("D")
# E = TypeVar("E")
# F = TypeVar("F")
# G = TypeVar("G")
# def compose() -> Callable[[A], A]:  # pylint: disable=function-redefined
# def compose(op1: Callable[[A], B]) -> Callable[[A], B]:  # pylint: disable=function-redefined
# def compose(op2: Callable[[B], C], op1: Callable[[A], B]) -> Callable[[A], C]:  # pylint: disable=function-redefined
# def compose(
#     op3: Callable[[C], D], op2: Callable[[B], C], op1: Callable[[A], B]  # pylint: disable=function-redefined
# ) -> Callable[[A], D]:
# def compose(
#     op4: Callable[[D], E],  # pylint: disable=function-redefined
#     op3: Callable[[C], D],
#     op2: Callable[[B], C],
#     op1: Callable[[A], B],
# ) -> Callable[[A], E]:
# def compose(
#     op5: Callable[[E], F],  # pylint: disable=function-redefined
#     op4: Callable[[D], E],
#     op3: Callable[[C], D],
#     op2: Callable[[B], C],
#     op1: Callable[[A], B],
# ) -> Callable[[A], F]:
# def compose(
#     op1: Callable[[A], B],  # pylint: disable=function-redefined,too-many-arguments
#     op2: Callable[[B], C],
#     op3: Callable[[C], D],
#     op4: Callable[[D], E],
#     op5: Callable[[E], F],
#     op6: Callable[[F], G],
# ) -> Callable[[A], G]:
# def compose(*funcs: Callable) -> Callable:  # type: ignore
#     def _compose(source: Any) -> Any:


import unittest
from oslash.cont import Cont
from oslash.util import identity, compose
        h = lambda x, abort: f(x) if x == 5 else abort(-1)

        do_c = lambda n: unit(n) | (
            lambda x: call_cc(lambda abort: h(x, abort) | (
                lambda y: g(y))))

        final_c = lambda x: "Done: %s" % x

        self.assertEqual(
            "Done: -1",
            do_c(4).run(final_c)
        )


class TestContFunctor(unittest.TestCase):

    def test_cont_functor_map(self):
        x = unit(42)
        f = lambda x: x * 10

        self.assertEqual(
            x.map(f),
            unit(420)
        )

    def test_cont_functor_law_1(self):
        # fmap id = id
        x = unit(42)

        self.assertEqual(

# Path: oslash/cont.py
# class Cont(Generic[T, TResult]):
#     """The Continuation Monad.
# 
#     The Continuation monad represents suspended computations in continuation-
#     passing style (CPS).
#     """
# 
#     def __init__(self, comp: Callable[[TCont], TResult]) -> None:
#         """Cont constructor.
# 
#         Keyword arguments:
#         cont -- A callable
#         """
#         self._comp = comp
# 
#     @classmethod
#     def unit(cls, value: T) -> 'Cont[T, TResult]':
#         """Create new continuation.
# 
#         Haskell: a -> Cont a
#         """
#         fn: Callable[[TCont], TResult] = lambda cont: cont(value)
#         return Cont(fn)
# 
#     def map(self, fn: Callable[[T], T2]) -> 'Cont[T2, TResult]':
#         r"""Map a function over a continuation.
# 
#         Haskell: fmap f m = Cont $ \c -> runCont m (c . f)
#         """
#         def comp(cont: Callable[[T2], TResult]) -> TResult:
#             return self.run(compose(cont, fn))
#         return Cont(comp)
# 
#     def bind(self, fn: Callable[[T], 'Cont[T2, TResult]']) -> 'Cont[T2, TResult]':
#         r"""Chain continuation passing functions.
# 
#         Haskell: m >>= k = Cont $ \c -> runCont m $ \a -> runCont (k a) c
#         """
#         return Cont(lambda cont: self.run(lambda a: fn(a).run(cont)))
# 
#     @staticmethod
#     def call_cc(fn: Callable) -> 'Cont':
#         r"""call-with-current-continuation.
# 
#         Haskell: callCC f = Cont $ \c -> runCont (f (\a -> Cont $ \_ -> c a )) c
#         """
#         return Cont(lambda c: fn(lambda a: Cont(lambda _: c(a))).run(c))
# 
#     def run(self, cont: Callable[[T], TResult]) -> TResult:
#         return self._comp(cont)
# 
#     def __or__(self, func):
#         """Use | as operator for bind.
# 
#         Provide the | operator instead of the Haskell >>= operator
#         """
#         return self.bind(func)
# 
#     def __call__(self, comp: Callable[[T], TResult]) -> TResult:
#         return self.run(comp)
# 
#     def __eq__(self, other) -> bool:
#         return self(identity) == other(identity)
# 
# Path: oslash/util/fn.py
# A = TypeVar("A")
# B = TypeVar("B")
# C = TypeVar("C")
# D = TypeVar("D")
# E = TypeVar("E")
# F = TypeVar("F")
# G = TypeVar("G")
# def compose() -> Callable[[A], A]:  # pylint: disable=function-redefined
# def compose(op1: Callable[[A], B]) -> Callable[[A], B]:  # pylint: disable=function-redefined
# def compose(op2: Callable[[B], C], op1: Callable[[A], B]) -> Callable[[A], C]:  # pylint: disable=function-redefined
# def compose(
#     op3: Callable[[C], D], op2: Callable[[B], C], op1: Callable[[A], B]  # pylint: disable=function-redefined
# ) -> Callable[[A], D]:
# def compose(
#     op4: Callable[[D], E],  # pylint: disable=function-redefined
#     op3: Callable[[C], D],
#     op2: Callable[[B], C],
#     op1: Callable[[A], B],
# ) -> Callable[[A], E]:
# def compose(
#     op5: Callable[[E], F],  # pylint: disable=function-redefined
#     op4: Callable[[D], E],
#     op3: Callable[[C], D],
#     op2: Callable[[B], C],
#     op1: Callable[[A], B],
# ) -> Callable[[A], F]:
# def compose(
#     op1: Callable[[A], B],  # pylint: disable=function-redefined,too-many-arguments
#     op2: Callable[[B], C],
#     op3: Callable[[C], D],
#     op4: Callable[[D], E],
#     op5: Callable[[E], F],
#     op6: Callable[[F], G],
# ) -> Callable[[A], G]:
# def compose(*funcs: Callable) -> Callable:  # type: ignore
#     def _compose(source: Any) -> Any:


# Path: tests/test_cont.py
import unittest
from oslash.cont import Cont
from oslash.util import identity, compose

        h = lambda x, abort: f(x) if x == 5 else abort(-1)

        do_c = lambda n: unit(n) | (
            lambda x: call_cc(lambda abort: h(x, abort) | (
                lambda y: g(y))))

        final_c = lambda x: "Done: %s" % x

        self.assertEqual(
            "Done: -1",
            do_c(4).run(final_c)
        )


class TestContFunctor(unittest.TestCase):

    def test_cont_functor_map(self):
        x = unit(42)
        f = lambda x: x * 10

        self.assertEqual(
            x.map(f),
            unit(420)
        )

    def test_cont_functor_law_1(self):
        # fmap id = id
        x = unit(42)

        self.assertEqual(

            x.map(identity),