Пример #1
0
    def test_build_sig_item(self):
        """Test type signature building internals - make sure that types are
           translated in a reasonable way"""
        class example:
            pass

        # type variables
        self.assertTrue(isinstance(build_sig_arg("a", {}, {}), TypeVariable))
        self.assertTrue(isinstance(build_sig_arg("abc", {}, {}), TypeVariable))

        # builtin/non-ADT types
        self.unified(build_sig_arg(str, {}, {}), TypeOperator(str, []))
        self.unified(build_sig_arg(int, {}, {}), TypeOperator(int, []))
        self.unified(build_sig_arg(float, {}, {}), TypeOperator(float, []))
        self.unified(build_sig_arg(list, {}, {}), TypeOperator(list, []))
        self.unified(build_sig_arg(set, {}, {}), TypeOperator(set, []))
        self.unified(build_sig_arg(example, {}, {}), TypeOperator(example, []))

        # unit type (None)
        self.unified(build_sig_arg(None, {}, {}), TypeOperator(None, []))

        # tuple
        self.unified(build_sig_arg((int, int), {}, {}),
                     Tuple([TypeOperator(int, []),
                            TypeOperator(int, [])]))
        self.unified(
            build_sig_arg((None, (None, int)), {}, {}),
            Tuple([
                TypeOperator(None, []),
                Tuple([TypeOperator(None, []),
                       TypeOperator(int, [])])
            ]))
        a = TypeVariable()
        self.unified(build_sig_arg(("a", "a", "a"), {}, {}), Tuple([a, a, a]))

        # list
        self.unified(typeof(L[[]]), build_sig_arg(["a"], {}, {}))
        self.unified(typeof(L[1, 1]), build_sig_arg([int], {}, {}))
        self.unified(typeof(L[[L[1, 1]]]), build_sig_arg([[int]], {}, {}))

        # adts
        self.unified(typeof(Nothing), build_sig_arg(t(Maybe, "a"), {}, {}))
        self.unified(typeof(Just(1)), build_sig_arg(t(Maybe, int), {}, {}))
        self.unified(typeof(Just(Just(Nothing))),
                     build_sig_arg(t(Maybe, t(Maybe, t(Maybe, "a"))), {}, {}))
        self.unified(typeof(Right("error")),
                     build_sig_arg(t(Either, str, "a"), {}, {}))
        self.unified(typeof(Left(2.0)),
                     build_sig_arg(t(Either, "a", int), {}, {}))
        self.unified(typeof(Just(__ + 1)),
                     build_sig_arg(t(Maybe, "a"), {}, {}))
        self.unified(typeof(Just(__ + 1)),
                     build_sig_arg(t(Maybe, (H / "a" >> "b")), {}, {}))
Пример #2
0
 def __next(self):
     """Evaluate the next element of the tail, and add it to the head."""
     from hask3.lang.type_system import typeof
     from hask3.lang.hindley_milner import unify
     if self.__is_evaluated:
         raise StopIteration
     else:
         try:
             next_iter = next(self.__tail)
             if len(self.__head) > 0:
                 unify(typeof(self[0]), typeof(next_iter))
             self.__head.append(next_iter)
         except StopIteration:
             self.__is_evaluated = True
Пример #3
0
 def __rxor__(self, item):
     """``^`` is the ``cons`` operator (equivalent to ``:`` in Haskell)."""
     from hask3.lang.type_system import typeof
     from hask3.lang.hindley_milner import ListType, unify
     unify(self.__type__(), ListType(typeof(item)))
     if self.__is_evaluated:
         return List(head=[item] + self.__head)
     return List(head=[item] + self.__head, tail=self.__tail)
Пример #4
0
 def __init__(self, head=None, tail=None):
     from itertools import chain
     from hask3.lang.type_system import typeof
     from hask3.lang.hindley_milner import unify
     if head is not None:
         count = len(head)
         if count > 0:
             fst = head[0]
             i = 1
             while i < count:
                 unify(typeof(fst), typeof(head[i]))
                 i += 1
         self.__head = list(head)
     else:
         self.__head = []
     self.__is_evaluated = tail is None
     self.__tail = chain([] if self.__is_evaluated else tail)
Пример #5
0
    def test_typecheck_builtins(self):
        """Make sure builtin types typecheck correctly"""

        # 1 :: int
        self.unified(typeof(1), TypeOperator(int, []))

        # "a" :: str
        self.unified(typeof("a"), TypeOperator(str, []))

        # Nothing :: Maybe a
        self.unified(typeof(Nothing), TypeOperator(Maybe, [TypeVariable()]))

        # Just(1) :: Maybe int
        self.unified(typeof(Just(1)),
                     TypeOperator(Maybe, [TypeOperator(int, [])]))

        # Just(Just(Nothing)) :: Maybe (Maybe (Maybe a))
        self.unified(
            typeof(Just(Just(Nothing))),
            TypeOperator(
                Maybe,
                [TypeOperator(Maybe, [TypeOperator(Maybe, [TypeVariable()])])
                 ]))

        # Right("error") :: Either a str
        self.unified(
            typeof(Right("error")),
            TypeOperator(
                Either, [TypeVariable(), TypeOperator(str, [])]))

        # Left(2.0) :: Either float a
        self.unified(
            typeof(Left(2.0)),
            TypeOperator(Either, [TypeOperator(float, []),
                                  TypeVariable()]))
Пример #6
0
 def __type__(self):
     from hask3.lang.type_system import typeof
     from hask3.lang.hindley_milner import TypeVariable, ListType
     if len(self.__head) == 0:
         if self.__is_evaluated:
             return ListType(TypeVariable())
         else:
             self.__next()
             return self.__type__()
     else:
         return ListType(typeof(self[0]))
Пример #7
0
    def __add__(self, other):
        """``(+) :: [a] -> [a] -> [a]``

        ``+`` is the list concatenation operator, equivalent to ``++`` in
        Haskell and + for Python lists

        """
        from itertools import chain
        from hask3.lang.type_system import typeof
        from hask3.lang.hindley_milner import unify
        unify(self.__type__(), typeof(other))
        if self.__is_evaluated and other.__is_evaluated:
            return List(head=self.__head + other.__head)
        elif self.__is_evaluated and not other.__is_evaluated:
            return List(head=self.__head + other.__head, tail=other.__tail)
        else:
            return List(head=self.__head, tail=chain(self.__tail, other))
Пример #8
0
def _t(obj):
    """Returns a string representing the type of an object.

    Includes higher-kinded types and ADTs.  Equivalent to ``:t`` in Haskell.
    Meant to be used in the REPL, but might also be useful for debugging.

    :param obj: the object to inspect.

    :returns: A string representation of the type.

    Usage::

        >>> from hask3 import _t

        >>> _t(1)
        'int'

        >>> _t(Just("hello world"))
        '(Maybe str)'

    """
    from hask3.lang.type_system import typeof
    return str(typeof(obj))
Пример #9
0
 def __contains__(self, x):
     from hask3.hack import isin
     from hask3.lang.type_system import typeof
     from hask3.lang.hindley_milner import ListType, unify
     unify(self.__type__(), ListType(typeof(x)))
     return isin(x, iter(self))
Пример #10
0
 def index(self, x):
     from hask3.lang.type_system import typeof
     from hask3.lang.hindley_milner import ListType, unify
     unify(self.__type__(), ListType(typeof(x)))
     self.__evaluate()
     return self.__head.index(x)