Ejemplo n.º 1
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))
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
 def maybe_fmap(fn, maybe_value):
     return ~(caseof(maybe_value)
                 | m(N)      >> N
                 | m(J(m.x)) >> J(fn(p.x))
             )
Ejemplo n.º 4
0
 def default_to_zero(x):
     return ~(caseof(x)
                 | m(Just(m.x)) >> p.x
                 | m(Nothing)   >> 0)
Ejemplo n.º 5
0
 def fib(x):
     return ~(caseof(x)
                 | m(0)   >> 1
                 | m(1)   >> 1
                 | m(m.n) >> fib(p.n - 2) + fib(p.n - 1)
             )