Skip to content

Optiont

OptionT dataclass

Bases: Generic[M, A]

OptionT is a monad transformer in the style of the mtl library for Haskell.

Source code in funclift/types/optiont.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@dataclass
class OptionT(Generic[M, A]):
    """
    OptionT is a monad transformer in the style of the mtl library for
    Haskell.
    """

    value: Monad[M, Option[A]]

    def run(self) -> Monad[M, Option[A]]:
        return self.value

    # def pure(self, a: E) -> OptionT[M, E]:
    #     return OptionT(self.value.pure(Some.pure(a)))

    def pure(self, option_e: Option[E]) -> OptionT[M, E]:
        return OptionT(self.value.pure(option_e))

    # def fmap(self, f: Callable[[A], B]) -> Some[B]:
    #     return Some(f(self.value))

    def flatmap(self, f: Callable[[A], OptionT[M, B]]) -> OptionT[M, B]:
        def foo(option_a: Option[A]) -> Monad[M, Option[B]]:
            if isinstance(option_a, Nothing):
                return self.value.pure(Nothing())
            else:
                return f(option_a.get()).value

        # self.value: IO[Option[A]]
        # foo: [Option[A]] -> IO[Option[B]]
        # self.value.flatmap(foo): IO[Option[B]]
        return OptionT(self.value.flatmap(foo))

    # def flatmap(self, f: Callable[[A], Option[B]]) -> OptionT[M, B]:
    #     def foo(option_a: Option[A]) -> Option[B]:
    #         if isinstance(option_a, Nothing):
    #             return Nothing()
    #         else:
    #             return f(option_a.get())

    #     return OptionT(self.value.fmap(foo))

    @staticmethod
    def lift(ma: Monad[M, A]) -> OptionT[M, A]:
        return OptionT(ma.fmap(lambda a: Some.pure(a)))