text: from abc import abstractmethod
  from typing import Callable, ClassVar, NoReturn, Sequence, Type, TypeVar
  
  from typing_extensions import final
  
  from returns.functions import compose, identity
  from returns.interfaces import mappable
  from returns.primitives.asserts import assert_equal
  from returns.primitives.hkt import KindN
  from returns.primitives.laws import (
      Law,
      Law1,
      Law3,
      Lawful,
      LawSpecDef,
      law_definition,
  )
  
  _FirstType = TypeVar('_FirstType')
  _SecondType = TypeVar('_SecondType')
  _ThirdType = TypeVar('_ThirdType')
  _UpdatedType = TypeVar('_UpdatedType')
  
  _ApplicativeType = TypeVar('_ApplicativeType', bound='ApplicativeN')
  
  # Only used in laws:
  _NewType1 = TypeVar('_NewType1')
  _NewType2 = TypeVar('_NewType2')
  
  
  @final
  class _LawSpec(LawSpecDef):
      """
      Applicative mappable laws.
  
      Definition: https://bit.ly/3hC8F8E
      Discussion: https://bit.ly/3jffz3L
      """
  
      __slots__ = ()
  
      @law_definition
      def identity_law(
          container: 'ApplicativeN[_FirstType, _SecondType, _ThirdType]',
      ) -> None:
          """
          Identity law.
  
          If we apply wrapped ``identity`` function to a container,
          nothing happens.
          """
          assert_equal(
              container,
              container.apply(container.from_value(identity)),
          )
  
      @law_definition
      def interchange_law(
          raw_value: _FirstType,
          container: 'ApplicativeN[_FirstType, _SecondType, _ThirdType]',
          function: Callable[[_FirstType], _NewType1],
      ) -> None:
          """
          Interchange law.
  
          Basically we check that we can start our composition
          with both ``raw_value`` and ``function``.
  
          Great explanation: https://stackoverflow.com/q/27285918/4842742
          """
          assert_equal(
              container.from_value(raw_value).apply(
                  container.from_value(function),
              ),
              container.from_value(function).apply(
                  container.from_value(lambda inner: inner(raw_value)),
              ),
          )
  
      @law_definition
      def homomorphism_law(
          raw_value: _FirstType,
          container: 'ApplicativeN[_FirstType, _SecondType, _ThirdType]',
          function: Callable[[_FirstType], _NewType1],
      ) -> None:
          """
          Homomorphism law.
  
          The homomorphism law says that
          applying a wrapped function to a wrapped value is the same
          as applying the function to the value in the normal way
          and then using ``.from_value`` on the result.
          """
          assert_equal(
              container.from_value(function(raw_value)),
              container.from_value(raw_value).apply(
                  container.from_value(function),
              ),
          )
  
      @law_definition
      def composition_law(
          container: 'ApplicativeN[_FirstType, _SecondType, _ThirdType]',
          first: Callable[[_FirstType], _NewType1],
          second: Callable[[_NewType1], _NewType2],
      ) -> None:
          """
          Composition law.
  
          Applying two functions twice is the same
          as applying their composition once.
          """
          assert_equal(
              container.apply(container.from_value(compose(first, second))),
              container.apply(
                  container.from_value(first),
              ).apply(
                  container.from_value(second),
              ),
          )
  
  
  class ApplicativeN(
      mappable.MappableN[_FirstType, _SecondType, _ThirdType],
      Lawful['ApplicativeN[_FirstType, _SecondType, _ThirdType]'],
  ):
      """
      Allows to create unit containers from raw values and to apply wrapped funcs.
  
      See also:
          - https://en.wikipedia.org/wiki/Applicative_functor
          - http://learnyouahaskell.com/functors-applicative-functors-and-monoids
  
      """
  
      __slots__ = ()
  
      _laws: ClassVar[Sequence[Law]] = (
          Law1(_LawSpec.identity_law),
          Law3(_LawSpec.interchange_law),
          Law3(_LawSpec.homomorphism_law),
          Law3(_LawSpec.composition_law),
      )
  
      @abstractmethod
      def apply(
          self: _ApplicativeType,
          container: KindN[
              _ApplicativeType,
              Callable[[_FirstType], _UpdatedType],
              _SecondType,
              _ThirdType,
          ],
      ) -> KindN[_ApplicativeType, _UpdatedType, _SecondType, _ThirdType]:
          """Allows to apply a wrapped function over a container."""
  
      @classmethod
      @abstractmethod
      def from_value(
          cls: Type[_ApplicativeType],  # noqa: N805
          inner_value: _UpdatedType,
      ) -> KindN[_ApplicativeType, _UpdatedType, _SecondType, _ThirdType]:
          """Unit method to create new containers from any raw value."""
  
  
  #: Type alias for kinds with one type argument.
  Applicative1 = ApplicativeN[_FirstType, NoReturn, NoReturn]
  
  #: Type alias for kinds with two type arguments.
  Applicative2 = ApplicativeN[_FirstType, _SecondType, NoReturn]
  
  #: Type alias for kinds with three type arguments.
  Applicative3 = ApplicativeN[_FirstType, _SecondType, _ThirdType]
  