# Path: oslash/identity.py
# class Identity(Generic[TSource]):
#     """Identity monad.
# 
#     The Identity monad is the simplest monad, which attaches no
#     information to values.
#     """
#     def __init__(self, value: TSource) -> None:
#         self._value = value
# 
#     @classmethod
#     def unit(cls, value: TSource) -> 'Identity[TSource]':
#         """Initialize a new identity."""
#         return Identity(value)
# 
#     def map(self, mapper: Callable[[TSource], TResult]) -> 'Identity[TResult]':
#         """Map a function over wrapped values."""
#         result = mapper(self._value)
#         return Identity(result)
# 
#     def bind(self, func: Callable[[TSource], 'Identity[TResult]']) -> 'Identity[TResult]':
#         return func(self._value)
# 
#     @classmethod
#     def pure(cls, value: TSource):
#         return Identity(value)
# 
#     def apply(self: 'Identity[Callable[[TSource], TResult]]', something: 'Identity[TSource]') -> 'Identity[TResult]':
#         def mapper(other_value):
#             try:
#                 return self._value(other_value)
#             except TypeError:
#                 return partial(self._value, other_value)
#         return something.map(mapper)
# 
#     def run(self) -> TSource:
#         return self._value
# 
#     def __call__(self) -> TSource:
#         return self.run()
# 
#     def __eq__(self, other) -> bool:
#         return self._value == other()
# 
#     def __str__(self) -> str:
#         return "Identity(%s)" % self._value
# 
#     def __repr__(self) -> str:
#         return str(self)
# 
# 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.identity import Identity
from oslash.util import identity, compose, fmap
        # fmap id = id
        x = unit(42)

        self.assertEqual(x.map(identity), x)

    def test_identity_functor_law2(self):
        # fmap (f . g) x = fmap f (fmap g x)
        def f(x):
            return x + 10

        def g(x):
            return x * 10

        x = unit(42)

        self.assertEqual(x.map(compose(f, g)), x.map(g).map(f))


class TestIdentityApplicative(unittest.TestCase):
    def test_identity_applicative_law_functor(self):
        # pure f <*> x = fmap f x
        x = unit(42)
        f = lambda x: x * 42

        self.assertEqual(pure(f).apply(x), x.map(f))

    def test_identity_applicative_law_identity(self):
        # pure id <*> v = v
        v = unit(42)


# Path: oslash/identity.py
# class Identity(Generic[TSource]):
#     """Identity monad.
# 
#     The Identity monad is the simplest monad, which attaches no
#     information to values.
#     """
#     def __init__(self, value: TSource) -> None:
#         self._value = value
# 
#     @classmethod
#     def unit(cls, value: TSource) -> 'Identity[TSource]':
#         """Initialize a new identity."""
#         return Identity(value)
# 
#     def map(self, mapper: Callable[[TSource], TResult]) -> 'Identity[TResult]':
#         """Map a function over wrapped values."""
#         result = mapper(self._value)
#         return Identity(result)
# 
#     def bind(self, func: Callable[[TSource], 'Identity[TResult]']) -> 'Identity[TResult]':
#         return func(self._value)
# 
#     @classmethod
#     def pure(cls, value: TSource):
#         return Identity(value)
# 
#     def apply(self: 'Identity[Callable[[TSource], TResult]]', something: 'Identity[TSource]') -> 'Identity[TResult]':
#         def mapper(other_value):
#             try:
#                 return self._value(other_value)
#             except TypeError:
#                 return partial(self._value, other_value)
#         return something.map(mapper)
# 
#     def run(self) -> TSource:
#         return self._value
# 
#     def __call__(self) -> TSource:
#         return self.run()
# 
#     def __eq__(self, other) -> bool:
#         return self._value == other()
# 
#     def __str__(self) -> str:
#         return "Identity(%s)" % self._value
# 
#     def __repr__(self) -> str:
#         return str(self)
# 
# 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_identity.py
import unittest
from oslash.identity import Identity
from oslash.util import identity, compose, fmap

        # fmap id = id
        x = unit(42)

        self.assertEqual(x.map(identity), x)

    def test_identity_functor_law2(self):
        # fmap (f . g) x = fmap f (fmap g x)
        def f(x):
            return x + 10

        def g(x):
            return x * 10

        x = unit(42)

        self.assertEqual(x.map(compose(f, g)), x.map(g).map(f))


class TestIdentityApplicative(unittest.TestCase):
    def test_identity_applicative_law_functor(self):
        # pure f <*> x = fmap f x
        x = unit(42)
        f = lambda x: x * 42

        self.assertEqual(pure(f).apply(x), x.map(f))

    def test_identity_applicative_law_identity(self):
        # pure id <*> v = v
        v = unit(42)


        self.assertEqual(pure(identity).apply(v), v)