Esempio n. 1
0
    def test_match(self):
        @sig(H/ int >> int)
        def fib(x):
            return ~(caseof(x)
                        | m(0)   >> 1
                        | m(1)   >> 1
                        | m(m.n) >> fib(p.n - 2) + fib(p.n - 1)
                    )

        self.assertEqual(1, fib(0))
        self.assertEqual(1, fib(1))
        self.assertEqual(13, fib(6))

        def default_to_zero(x):
            return ~(caseof(x)
                        | m(Just(m.x)) >> p.x
                        | m(Nothing)   >> 0)

        self.assertEqual(default_to_zero(Just(27)), 27)
        self.assertEqual(default_to_zero(Nothing), 0)
        self.assertEqual(Just(20.0)[0], 20.0)
        self.assertEqual(Left("words words words words")[0],
                         "words words words words")
        with self.assertRaises(IndexError):
            Nothing[0]
Esempio n. 2
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()]))
Esempio n. 3
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")), {}, {}))
Esempio n. 4
0
 def test_show(self):
     from hask3.Prelude import show
     self.assertEqual("Just(3)", str(Just(3)))
     self.assertEqual("Just(3)", show(Just(3)))
     self.assertEqual("Just('a')", str(Just("a")))
     self.assertEqual("Just('a')", show(Just("a")))
     self.assertEqual("Just(Just(3))", str(Just(Just(3))))
     self.assertEqual("Just(Just(3))", show(Just(Just(3))))
     self.assertEqual("Nothing", str(Nothing))
     self.assertEqual("Nothing", show(Nothing))
Esempio n. 5
0
    def test_typeclasses(self):
        from hask3.Prelude import fmap
        M, N, J = data.M("a") == d.N | d.J("a") & deriving(Show, Eq, Ord)

        def maybe_fmap(fn, maybe_value):
            return ~(caseof(maybe_value)
                        | m(N)      >> N
                        | m(J(m.x)) >> J(fn(p.x))
                    )

        instance(Functor, M).where(
            fmap = maybe_fmap
        )

        times2 = (lambda x: x * 2) ** (H/ int >> int)
        toFloat = float ** (H/ int >> float)

        self.assertEqual(fmap(toFloat, J(10)), J(10.0))
        self.assertEqual(fmap(toFloat, fmap(times2, J(25))), J(50.0))
        self.assertEqual((toFloat * times2) * J(25), J(50.0))
        self.assertEqual((toFloat * times2) * N, N)

        instance(Applicative, M).where(
            pure = J
        )

        instance(Monad, M).where(
            bind = lambda x, f: ~(caseof(x)
                                    | m(J(m.a)) >> f(p.a)
                                    | m(N)   >> N)
        )

        @sig(H/ int >> int >> t(M, int))
        def safe_div(x, y):
            return N if y == 0 else J(x//y)

        from hask3.Prelude import flip
        divBy = flip(safe_div)
        self.assertEqual(J(9) >> divBy(3), J(3))

        self.assertEqual(Just(12) >> divBy(2) >> divBy(2) >> divBy(3), J(1))
        self.assertEqual(J(12) >> divBy(0) >> divBy(6), N)

        from hask3.Data.List import replicate
        self.assertEqual(L[1, 2] >> replicate(2) >> replicate(2),
                L[1, 1, 1, 1, 2, 2, 2, 2])

        class Person:
            def __init__(self, name, age):
                self.name = name
                self.age = age

        instance(Eq, Person).where(
            eq = lambda p1, p2: p1.name == p2.name and p1.age == p2.age
        )

        self.assertFalse(Person("Philip Wadler", 59) == Person("Simon Peyton Jones", 57))
Esempio n. 6
0
    def test_examples(self):
        @sig(H/ int >> int >> t(Maybe, int))
        def safe_div(x, y):
            return Nothing if y == 0 else Just(x//y)

        from hask3.Data.Maybe import mapMaybe
        self.assertEqual(mapMaybe(safe_div(12)) % L[0, 1, 3, 0, 6],
                         L[12, 4, 2])

        from hask3.Data.List import isInfixOf
        self.assertTrue(isInfixOf(L[2, 8], L[1, 4, 6, 2, 8, 3, 7]))

        from hask3.Control.Monad import join
        self.assertEqual(join(Just(Just(1))), Just(1))

        from hask3.Prelude import flip
        from hask3.Data.Tuple import snd
        from hask3.Python.builtins import divmod, hex

        hexMod = hex * snd * flip(divmod, 16)
        self.assertEqual(hexMod(24), '0x8')
Esempio n. 7
0
    def test_building_lists(self):
        from hask3.Data.List import scanl, scanl1, scanr, scanr1, mapAccumL  # noqa: F401
        from hask3.Data.List import mapAccumR, iterate, repeat, replicate, cycle  # noqa: F401
        from hask3.Data.List import unfoldr

        plus_one = (lambda x: x + 1)**(H / int >> int)
        self.assertEquals(iterate(plus_one, 0)[:10], L[range(10)])
        self.assertEquals(iterate(__ + 1, 0)[:10], L[range(10)])

        uf = (lambda x: Nothing if x > 5 else Just((x+1, x+1))) ** \
                (H/ int >> t(Maybe, (int, int)))
        self.assertEquals(L[[]], unfoldr(uf, 6))
        self.assertEquals(L[1, ..., 6], unfoldr(uf, 0))
Esempio n. 8
0
    def test_decorators(self):
        def eat_cheese(cheese):
            if cheese <= 0:
                raise ValueError("Out of cheese error")
            return cheese - 1

        maybe_eat = in_maybe(eat_cheese)
        self.assertEqual(maybe_eat(1), Just(0))
        self.assertEqual(maybe_eat(0), Nothing)
        self.assertEqual(Just(6), Just(7) >> maybe_eat)
        self.assertEqual(Just(7),
                         Just(10) >> maybe_eat >> maybe_eat >> maybe_eat)
        self.assertEqual(Nothing,
                         Just(1) >> maybe_eat >> maybe_eat >> maybe_eat)

        either_eat = in_either(eat_cheese)
        self.assertEqual(either_eat(10), Right(9))
        self.assertTrue(isinstance(either_eat(0)[0], ValueError))
Esempio n. 9
0
 def safe_div(x, y):
     return Nothing if y == 0 else Just(x//y)
Esempio n. 10
0
    def test_functions(self):
        from hask3.Data.Maybe import maybe, isJust, isNothing, fromJust
        from hask3.Data.Maybe import fromMaybe
        from hask3.Data.Maybe import listToMaybe, maybeToList, catMaybes
        from hask3.Data.Maybe import mapMaybe

        self.assertTrue(isJust(Just(1)))
        self.assertTrue(isJust(Just(Nothing)))
        self.assertFalse(isJust(Nothing))
        self.assertFalse(isNothing(Just(1)))
        self.assertFalse(isNothing(Just(Nothing)))
        self.assertTrue(isNothing(Nothing))
        self.assertEqual(fromJust(Just("bird")), "bird")
        self.assertEqual(fromJust(Just(Nothing)), Nothing)
        with self.assertRaises(ValueError):
            fromJust(Nothing)

        self.assertEqual(2, maybe(0, (__ + 1), Just(1)))
        self.assertEqual(0, maybe(0, (__ + 1)) % Nothing)
        self.assertEqual(Nothing, listToMaybe(L[[]]))
        self.assertEqual(Just("a"), listToMaybe(L[["a"]]))
        self.assertEqual(Just("a"), listToMaybe(L["a", "b"]))
        self.assertEqual(Just(1), listToMaybe(L[1, ...]))
        self.assertEqual(L[[]], maybeToList(Nothing))
        self.assertEqual(L[[1]], maybeToList(Just(1)))
        self.assertEqual(L[[]], catMaybes(L[[]]))
        self.assertEqual(L[[]], catMaybes(L[Nothing, Nothing]))
        self.assertEqual(L[1, 2], catMaybes(L[Just(1), Just(2)]))
        self.assertEqual(L[1, 2], catMaybes(L[Just(1), Nothing, Just(2)]))

        from hask3.Prelude import const
        self.assertEqual(L[[]], mapMaybe(const(Nothing), L[1, 2]))
        self.assertEqual(L[1, 2], mapMaybe(Just, L[1, 2]))
        self.assertEqual(L[[]], mapMaybe(Just, L[[]]))

        f = (lambda x: Just(x) if x > 3 else Nothing) \
            ** (H/ int >> t(Maybe, int))
        self.assertEqual(L[4, 5], mapMaybe(f, L[1, ..., 5]))
        self.assertEqual(L[[]], mapMaybe(f, L[1, ..., 3]))

        self.assertEqual(1, fromMaybe(1, Nothing))
        self.assertEqual(2, fromMaybe(1, Just(2)))
Esempio n. 11
0
 def safediv(x, y):
     return Just(x // y) if y != 0 else Nothing
Esempio n. 12
0
    def test_monad(self):
        f = (lambda x: Just(str(x)))**(H / int >> t(Maybe, str))
        g = (lambda x: Just(x * 10))**(H / int >> t(Maybe, int))
        self.assertEqual(Just("1"), Just(1) >> f)
        self.assertEqual(Just(10), Just(1) >> g)
        self.assertEqual(Just(1000), Just(1) >> g >> g >> g)

        @sig(H[(Num, "a")] / "a" >> "a" >> t(Maybe, "a"))
        def safediv(x, y):
            return Just(x // y) if y != 0 else Nothing

        from hask3.Prelude import flip
        s = flip(safediv)
        self.assertEqual(Just(3), Just(9) >> s(3))
        self.assertEqual(Just(1), Just(9) >> s(3) >> s(3))
        self.assertEqual(Nothing, Just(9) >> s(0) >> s(3))
        self.assertEqual(Nothing, Nothing >> s(3) >> s(3))

        # monad laws
        s_composed = (lambda x: s(3, x) >> s(3))**(H / int >> t(Maybe, int))
        self.assertEqual(Just(2), Just(2) >> Just)
        self.assertEqual(Nothing, Nothing >> Just)
        self.assertEqual(Just(4) >> s(2), s(2, 4))
        self.assertEqual(Just(1), (Just(9) >> s(3)) >> s(3))
        self.assertEqual(Just(1), Just(9) >> s_composed)
        self.assertEqual(Nothing, (Nothing >> s(3)) >> s(3))
        self.assertEqual(Nothing, Nothing >> s_composed)

        from hask3.Control.Monad import join, liftM
        self.assertEqual(join(Just(Just(1))), Just(1))
        self.assertEqual(join(Just(Nothing)), Nothing)
        self.assertEqual(liftM(__ + 1, Just(1)), Just(2))
        self.assertEqual(liftM(__ + 1, Nothing), Nothing)
Esempio n. 13
0
    def test_functor(self):
        from hask3.Prelude import id, fmap
        plus1 = (lambda x: x + 1)**(H / int >> int)
        toStr = str**(H / int >> str)

        self.assertEqual(Just(Just(2)), fmap(Just, Just(2)))
        self.assertEqual(Just(3), plus1 * Just(2))
        self.assertEqual(Just("1"), toStr * Just(1))
        self.assertEqual(Just("3"), (toStr * plus1) * Just(2))

        # functor laws
        self.assertEqual(fmap(id, Just(4)), Just(4))
        self.assertEqual(fmap(id, Nothing), Nothing)
        self.assertEqual(id * Just(4), Just(4))
        self.assertEqual(id * Nothing, Nothing)
        self.assertEqual(fmap(toStr, fmap(plus1, Just(2))),
                         fmap(toStr * plus1, Just(2)))
        self.assertEqual((toStr * (plus1 * Just(2))),
                         (toStr * plus1) * Just(2))
Esempio n. 14
0
    def test_sig(self):
        @sig(H/ "a" >> "b" >> "a")
        def const(x, y):
            return x
        self.assertEqual(const(1, 2), 1)

        def const(x, y):
            return x
        const = const ** (H/ "a" >> "b" >> "a")
        self.assertEqual(const(1, 2), 1)

        f = (lambda x, y: x + y) ** (H/ int >> int >> int)
        self.assertEqual(5, f(2, 3))
        with self.assertRaises(TypeError):
            f(9, 1.0)

        g = (lambda a, b, c: a // (b + c)) ** (H/ int >> int >> int >> int)
        self.assertEqual(g(10, 2, 3), 2)
        part_g = g(12)
        self.assertEqual(part_g(2, 2), 3)
        self.assertEqual(g(20, 1)(4), 4)
        self.assertEqual(Just * Just * Just * Just % 77, Just(Just(Just(Just(77)))))

        # add two ints together
        @sig(H/ int >> int >> int)
        def add(x, y):
            return x + y

        # reverse order of arguments to a function
        @sig(H/ (H/ "a" >> "b" >> "c") >> "b" >> "a" >> "c")
        def flip(f, b, a):
            return f(a, b)

        # map a Python (untyped) function over a Python (untyped) set
        @sig(H/ func >> set >> set)
        def set_map(fn, lst):
            return set((fn(x) for x in lst))

        # map a typed function over a List
        @sig(H/ (H/ "a" >> "b") >> ["a"] >> ["b"])
        def map(f, xs):
            return L[(f(x) for x in xs)]

        # type signature with an Eq constraint
        @sig(H[(Eq, "a")]/ "a" >> ["a"] >> bool)
        def not_in(y, xs):
            return not any((x == y for x in xs))

        # type signature with a type constructor (Maybe) that has type arguments
        @sig(H/ int >> int >> t(Maybe, int))
        def safe_div(x, y):
            return Nothing if y == 0 else Just(x//y)

        # type signature for a function that returns nothing
        @sig(H/ int >> None)
        def launch_missiles(num_missiles):
            return

        Ratio, R =\
                data.Ratio("a") == d.R("a", "a") & deriving(Eq)

        Rational = t(Ratio, int)


        @sig(H/ Rational >> Rational >> Rational)
        def addRational(rat1, rat2):
            pass

        from hask3.Prelude import flip
        h = (lambda x, y: x / y) ** (H/ float >> float >> float)
        self.assertEqual(h(3.0) * h(6.0) * flip(h, 2.0) % 36.0, 9.0)
Esempio n. 15
0
 def default_to_zero(x):
     return ~(caseof(x)
                 | m(Just(m.x)) >> p.x
                 | m(Nothing)   >> 0)
Esempio n. 16
0
    def test_match(self):
        match_only = lambda v, p: pattern_match(v, p)[0]
        pb = PatternMatchBind

        # literal matches
        self.assertTrue(match_only(1, 1))
        self.assertTrue(match_only((1, "a"), (1, "a")))
        self.assertTrue(match_only(Nothing, Nothing))
        self.assertTrue(match_only(Just(1), Just(1)))
        self.assertFalse(match_only(2, 1))
        self.assertFalse(match_only(("a", 1), (1, "a")))
        self.assertFalse(match_only(("a", "b"), ["a", "b"]))
        self.assertFalse(match_only(Nothing, Just(Nothing)))
        self.assertFalse(match_only(Just(2), Just(1)))
        self.assertFalse(match_only(Right(2), Just(2)))
        self.assertFalse(match_only(Right(2), Left(2)))

        # matches with wildcard (i.e, discarded variable bind)
        self.assertTrue(match_only(1, pb("_")))
        self.assertTrue(match_only(Nothing, pb("_")))
        self.assertTrue(match_only(Just("whatever"), Just(pb("_"))))
        self.assertTrue(match_only(Right(Just(5)), Right(Just(pb("_")))))
        self.assertTrue(match_only(("a", "b", "c"), ("a", pb("_"), "c")))
        self.assertFalse(match_only(("a", "b", "c"), ("1", pb("_"), "c")))
        self.assertFalse(match_only(("a", "b", "d"), ("a", pb("_"), "c")))

        # matches with variable binding
        self.assertEqual((True, {"a": 1}), pattern_match(1, pb("a")))
        self.assertEqual((True, {
            "a": 1,
            "b": 2
        }), pattern_match((1, 2), (pb("a"), pb("b"))))
        self.assertEqual((True, {
            "a": 8
        }), pattern_match(Just(8), Just(pb("a"))))
        self.assertEqual((True, {
            "a": "a"
        }), pattern_match(Right(Just("a")), Right(Just(pb("a")))))
        self.assertEqual((False, {
            "a": 1
        }), pattern_match((2, 1), (3, pb("a"))))
        self.assertEqual((True, {
            "a": 1,
            "b": 2,
            "_": "a"
        }), pattern_match((1, "a", 2), (pb("a"), pb("_"), pb("b"))))

        with self.assertRaises(SyntaxError):
            pattern_match((1, 2), (pb("c"), pb("a")), {"c": 1})
        with self.assertRaises(SyntaxError):
            pattern_match((1, 2), (pb("c"), pb("a")), {"a": 1})
Esempio n. 17
0
 def test_eq(self):
     self.assertEqual(Nothing, Nothing)
     self.assertEqual(Just(3), Just(3))
     self.assertEqual(Just("3"), Just("3"))
     self.assertNotEqual(Just(1), Just(3))
     self.assertNotEqual(Just(3), Nothing)
     self.assertNotEqual(Nothing, Just(0))
     self.assertTrue(Just(1) == Just(1))
     self.assertFalse(Just(1) == Just(2))
     self.assertTrue(Nothing == Nothing or Nothing != Nothing)
     self.assertTrue(Just(1) == Just(1) or Just(1) != Just(1))
     self.assertFalse(Nothing == Nothing and Nothing != Nothing)
     self.assertFalse(Just(1) == Just(1) and Just(1) != Just(1))
     with self.assertRaises(TypeError):
         Just(1) == Just("1")
     with self.assertRaises(TypeError):
         Just(1) == Just(1.0)
     with self.assertRaises(TypeError):
         Nothing == None  # noqa
     with self.assertRaises(TypeError):
         Nothing == 1
     with self.assertRaises(TypeError):
         Just(1) == 1
Esempio n. 18
0
    def test_ord(self):
        self.assertTrue(Nothing < Just(0))
        self.assertTrue(Nothing < Just("a"))
        self.assertTrue(Nothing < Just(-float("inf")))
        self.assertTrue(Nothing <= Just(0))
        self.assertTrue(Nothing <= Just("a"))
        self.assertTrue(Nothing <= Just(-float("inf")))
        self.assertTrue(Nothing >= Nothing and Nothing <= Nothing)
        self.assertFalse(Nothing > Just(0))
        self.assertFalse(Nothing > Just("a"))
        self.assertFalse(Nothing > Just(-float("inf")))
        self.assertFalse(Nothing >= Just(0))
        self.assertFalse(Nothing >= Just("a"))
        self.assertFalse(Nothing >= Just(-float("inf")))
        self.assertFalse(Nothing > Nothing or Nothing < Nothing)

        self.assertTrue(Just(1) > Just(0))
        self.assertTrue(Just(Just(1)) > Just(Nothing))
        self.assertTrue(Just(Just(Nothing)) > Just(Nothing))
        self.assertTrue(Just(1) >= Just(0))
        self.assertTrue(Just(1) >= Just(1))
        self.assertTrue(Just(Just(1)) >= Just(Nothing))
        self.assertTrue(Just(Just(Nothing)) >= Just(Nothing))
        self.assertTrue(Just(Just(Nothing)) >= Just(Just(Nothing)))
        self.assertFalse(Just(0) > Just(1))
        self.assertFalse(Just(0) > Just(0))
        self.assertFalse(Just(Nothing) > Just(Just(1)))
        self.assertFalse(Just(Nothing) > Just(Just(Nothing)))
        self.assertFalse(Just(0) >= Just(1))
        self.assertFalse(Just(Nothing) >= Just(Just(1)))
        self.assertFalse(Just(Nothing) >= Just(Just(Nothing)))

        self.assertTrue(Just(0) < Just(1))
        self.assertTrue(Just(Nothing) < Just(Just(1)))
        self.assertTrue(Just(Nothing) < Just(Just(Nothing)))
        self.assertTrue(Just(0) <= Just(1))
        self.assertTrue(Just(Nothing) <= Just(Just(1)))
        self.assertTrue(Just(Nothing) <= Just(Just(Nothing)))
        self.assertFalse(Just(1) < Just(0))
        self.assertFalse(Just(1) < Just(1))
        self.assertFalse(Just(Just(1)) < Just(Nothing))
        self.assertFalse(Just(Just(Nothing)) < Just(Nothing))
        self.assertFalse(Just(1) <= Just(0))
        self.assertTrue(Just(1) <= Just(1))
        self.assertFalse(Just(Just(1)) <= Just(Nothing))
        self.assertFalse(Just(Just(Nothing)) <= Just(Nothing))
        self.assertTrue(Just(Just(Nothing)) <= Just(Just(Nothing)))

        with self.assertRaises(TypeError):
            Just(1) > Just(1.0)
        with self.assertRaises(TypeError):
            Just(1) >= Just(1.0)
        with self.assertRaises(TypeError):
            Just(1) < Just(1.0)
        with self.assertRaises(TypeError):
            Just(1) <= Just(1.0)
        with self.assertRaises(TypeError):
            Just(1) > Just(Just(1))
        with self.assertRaises(TypeError):
            Just(1) >= Just(Just(1))
        with self.assertRaises(TypeError):
            Just(1) < Just(Just(1))
        with self.assertRaises(TypeError):
            Just(1) <= Just(Just(1))
Esempio n. 19
0
    def test_caseof(self):
        # literal matching
        self.assertEqual(1, ~(caseof("a") | m("a") >> 1))
        self.assertEqual(
            1, ~(caseof(2.0)
                 | m(2.0) >> ~(caseof("a")
                               | m("b") >> 3
                               | m("a") >> 1)
                 | m(2.0) >> 2))
        self.assertEqual(
            "x", ~(caseof(Just("x"))
                   | m(Nothing) >> False
                   | m(Just("x")) >> "x"))
        self.assertEqual(1, ~(caseof([1, 2])
                              | m((1, 2)) >> 2
                              | m([1, 2]) >> 1))
        self.assertEqual(
            True, ~(caseof(GT)
                    | m(LT) >> False
                    | m(EQ) >> False
                    | m(GT) >> True))
        self.assertEqual(
            2, ~(caseof((1, 2, 3))
                 | m((1, 2)) >> 1
                 | m((1, 2, 3)) >> 2))

        with self.assertRaises(IncompletePatternError):
            ~(caseof(1) | m(2) >> 2)

        # matches with wildcard
        self.assertEqual(1, ~(caseof(1) | m(m._) >> 1 | m(1) >> 2))
        self.assertEqual(
            True, ~(caseof(GT)
                    | m(LT) >> False
                    | m(EQ) >> False
                    | m(m._) >> True))
        self.assertEqual(
            False, ~(caseof(GT)
                     | m(LT) >> False
                     | m(m._) >> False
                     | m(GT) >> True))
        self.assertEqual(
            2, ~(caseof((1, 2, 3))
                 | m((2, 1, 3)) >> 1
                 | m((1, m._, 3)) >> 2
                 | m((1, 2, 3)) >> 3))

        # variable bind
        self.assertEqual(("b", "a"), ~(caseof(("a", "b"))
                                       | m((m.x, m.y)) >> (p.y, p.x)
                                       | m(m._) >> None))
        self.assertEqual(
            1, ~(caseof(Just(1))
                 | m(Just(m.x)) >> p.x
                 | m(Nothing) >> 0))
        self.assertEqual(
            Just(0), ~(caseof(Nothing)
                       | m(Just(m.x)) >> Just(p.x + 1)
                       | m(Nothing) >> Just(0)))
        self.assertEqual(1, ~(caseof(2) | m((m.a, m.a)) >> p.a | m(2) >> 1))
        self.assertEqual(
            1, ~(caseof(Just(10))
                 | m(Just(m.a)) >> ~(caseof(1)
                                     | m(m.a) >> p.a
                                     | m(m._) >> False)
                 | m(Nothing) >> 11))

        # cons matches
        self.assertEqual([3], ~(caseof([1, 2, 3])
                                | m(1 ^ (2 ^ m.x)) >> p.x
                                | m(m.x) >> False))
        self.assertEqual([3, 2, 1], ~(caseof([3, 2, 1])
                                      | m(m.a ^ (2 ^ m.c)) >> [p.a, 2, p.c[0]]
                                      | m(m.x) >> False))
        self.assertEqual([3, 2, [1, 0]],
                         ~(caseof([3, 2, 1, 0])
                           | m(m.a ^ (m.b ^ m.c)) >> [p.a, p.b, p.c]
                           | m(m.x) >> False))
        self.assertEqual(
            L[3, 2, 1], ~(caseof(L[3, 2, 1, 0])
                          | m(m.a ^ (m.b ^ m.c)) >> L[p.a, p.b, p.c[0]]
                          | m(m.x) >> False))
        self.assertEqual(
            1, ~(caseof(L[1, ...])
                 | m(m.a ^ m.b) >> p.a
                 | m(m.a) >> False))
        self.assertTrue(~(caseof(L[[]])
                          | m(m.a ^ m.b) >> False
                          | m(m.a) >> True))

        with self.assertRaises(SyntaxError):
            ~(caseof((1, 2)) | m((m.a, m.a)) >> p.a | m(1) >> 1)
        with self.assertRaises(SyntaxError):
            ~(caseof([1, 2, 3, 4])
              | m(m.a ^ m.b ^ m.c) >> True
              | m(m.x) >> False)
        with self.assertRaises(SyntaxError):
            ~(caseof(L[1, 2, 2]) | m(m.a ^ 1) >> False | m(m.a) >> True)