Skip to content

Option

Nothing dataclass

Bases: Option[Any]

Nothing

Source code in funclift/types/option.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
@dataclass
class Nothing(Option[Any]):
    """Nothing"""

    mtype: ClassVar[type] = Option

    def get(self) -> Any:
        raise FunctorValueError(self)

    # @staticmethod
    # def pure(a: E) -> Nothing[E]:
    #     return Nothing()

    def fmap(self, f: Callable[[A], B]) -> Nothing:
        return Nothing()

    def flatmap(self, f: Callable[[A], Option[B]]) -> Nothing:
        return Nothing()

    # def ap(self, a: Option) -> Option:
    def ap(self, other: Option[C]) -> Nothing:
        return Nothing()

    def traverse(self, f: Callable[[A], AP_B]) -> Applicative[AP, Option[B]]:
        # return IO.pure(Nothing())
        sig = signature(f)
        return sig.return_annotation.pure(Nothing())

Option

Bases: Generic[A]

The Option class represents one of two cases: something or nothing. The case of nothing is modeled by the Nothing class. The case of something is modeled by the Some class.

Option is a Monad. It is parameterized by a type variable A. When an Option object contains something, A is the type of that something. When an Option object contains nothing, A will match any type.

Source code in funclift/types/option.py
 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
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class Option(Generic[A]):
    """
    The Option class represents one of two cases: something or nothing.
    The case of nothing is modeled by the
    [`Nothing`][funclift.types.option.Nothing] class. The case of something
    is modeled by the [`Some`][funclift.types.option.Some] class.

    Option is a [`Monad`][funclift.monad.Monad]. It is parameterized by
    a type variable A. When an Option object contains something, A is
    the type of that something. When an Option object contains nothing,
    A will match any type.
    """

    @staticmethod
    def pure(a: E) -> Some[E]:
        """Creates a [`Some`][funclift.types.option.Some] instance that
        contains the passed-in parameter as its value.

        Args:
            a (E): value to be contained in a
            [`Some`][funclift.types.option.Some] instance

        Returns:
            Some[E]: a [`Some`][funclift.types.option.Some] instance that
            contains the passed-in parameter as its value.
        """
        return Some(a)

    @staticmethod
    def empty() -> Nothing:
        """_summary_

        Returns:
            Nothing: _description_
        """
        return Nothing()

    @staticmethod
    def create(value: A | None) -> Option[A]:
        """Creates an Option instance. Returns a Nothing instance if the
        passed-in value is None; otherwise, returns a Some instance.

        Args:
            value (A | None): a value to be wrapped up in an Option instance.

        Returns:
            Option[A]: the returned Option instance.
        """
        if value is None:
            return Nothing()
        else:
            return Some(value)

    @abstractmethod
    def get(self) -> A:
        """_summary_

        Returns:
            A: _description_
        """
        ...

    def __iter__(self) -> Iterator[A]:
        yield self.get()

    # Need to repeat this to make mypy happy or else mypy will think
    # the return type is Functor[B]
    @abstractmethod
    def fmap(self, f: Callable[[A], B]) -> Option[B]:
        """Option is a Functor and therefore implements the fmap method.
        Need to repeat this to make mypy happy or else mypy will think
        the return type is Functor[F, B]. See the fmap method in
        [`Functor`][funclift.functor.Functor] for details.
        """
        ...

    @abstractmethod
    def flatmap(self, f: Callable[[A], Option[B]]) -> Option[B]:
        ...

    @abstractmethod
    def ap(self: Option[Callable[[C], E]], a: Option[C]) -> Option[E]:
        ...

    # def ap(fab: Option[Callable[[A], B]], a: Option[A]) -> Option[B]: ...
    # @abstractmethod
    # def ap2(self, f: Option[Callable[[A], B]]) -> Option[B]: ...

    @staticmethod
    def product(d: Option[D], e: Option[E]) -> Option[tuple[D, E]]:
        if isinstance(d, Nothing):
            return Nothing()

        if isinstance(e, Nothing):
            return Nothing()

        # return Some.product(d, e)
        return Some((d.get(), e.get()))

    @classmethod
    def do(cls, expr: Generator[B, None, None]) -> Option[B]:
        try:
            return Some.pure(next(expr))
        except FunctorValueError as exc:
            return exc.halted_container

create(value) staticmethod

Creates an Option instance. Returns a Nothing instance if the passed-in value is None; otherwise, returns a Some instance.

Parameters:

Name Type Description Default
value A | None

a value to be wrapped up in an Option instance.

required

Returns:

Type Description
Option[A]

Option[A]: the returned Option instance.

Source code in funclift/types/option.py
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@staticmethod
def create(value: A | None) -> Option[A]:
    """Creates an Option instance. Returns a Nothing instance if the
    passed-in value is None; otherwise, returns a Some instance.

    Args:
        value (A | None): a value to be wrapped up in an Option instance.

    Returns:
        Option[A]: the returned Option instance.
    """
    if value is None:
        return Nothing()
    else:
        return Some(value)

empty() staticmethod

summary

Returns:

Name Type Description
Nothing Nothing

description

Source code in funclift/types/option.py
51
52
53
54
55
56
57
58
@staticmethod
def empty() -> Nothing:
    """_summary_

    Returns:
        Nothing: _description_
    """
    return Nothing()

fmap(f) abstractmethod

Option is a Functor and therefore implements the fmap method. Need to repeat this to make mypy happy or else mypy will think the return type is Functor[F, B]. See the fmap method in Functor for details.

Source code in funclift/types/option.py
90
91
92
93
94
95
96
97
@abstractmethod
def fmap(self, f: Callable[[A], B]) -> Option[B]:
    """Option is a Functor and therefore implements the fmap method.
    Need to repeat this to make mypy happy or else mypy will think
    the return type is Functor[F, B]. See the fmap method in
    [`Functor`][funclift.functor.Functor] for details.
    """
    ...

get() abstractmethod

summary

Returns:

Name Type Description
A A

description

Source code in funclift/types/option.py
76
77
78
79
80
81
82
83
@abstractmethod
def get(self) -> A:
    """_summary_

    Returns:
        A: _description_
    """
    ...

pure(a) staticmethod

Creates a Some instance that contains the passed-in parameter as its value.

Parameters:

Name Type Description Default
a E

value to be contained in a

required

Returns:

Type Description
Some[E]

Some[E]: a Some instance that

Some[E]

contains the passed-in parameter as its value.

Source code in funclift/types/option.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@staticmethod
def pure(a: E) -> Some[E]:
    """Creates a [`Some`][funclift.types.option.Some] instance that
    contains the passed-in parameter as its value.

    Args:
        a (E): value to be contained in a
        [`Some`][funclift.types.option.Some] instance

    Returns:
        Some[E]: a [`Some`][funclift.types.option.Some] instance that
        contains the passed-in parameter as its value.
    """
    return Some(a)

Some dataclass

Bases: Option[A]

Some

Source code in funclift/types/option.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
@dataclass
class Some(Option[A]):
    """Some"""

    value: A
    mtype: ClassVar[type] = Option

    def get(self) -> A:
        return self.value

    @staticmethod
    # def pure(a: A) -> Some[A]:
    def pure(a: E) -> Some[E]:
        return Some(a)

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

    def flatmap(self, f: Callable[[A], Option[B]]) -> Option[B]:
        result = f(self.value)
        return result

    # This won't work because E does not come from anywhere
    # def ap(self, other: Option[D]) -> Option[E]:
    #     return other.fmap(cast(Callable[[D], E], self.value))

    def ap(self: Some[Callable[[C], E]], other: Option[C]) -> Option[E]:
        return other.fmap(self.value)
        # return other.ap2(self.value)

    # @staticmethod
    # def product(d: Some[D], e: Some[E]) -> Some[tuple[D, E]]:
    #     return Some((d.value, e.value))

    def traverse(self: Some[A],
                 f: Callable[[A], AP_B]) -> Applicative[AP, Some[B]]:
        ap_b: Applicative[AP, B] = f(self.value)
        return ap_b.fmap(lambda x: Some(x))