Skip to content

Peekable

Bases: PyoIterator[T]


              flowchart TD
              pyochain.core._iterators.Peekable[Peekable]
              pyochain.abc._iterator.PyoIterator[PyoIterator]
              pyochain.abc._iterable.PyoIterable[PyoIterable]
              pyochain.abc._mixins.Checkable[Checkable]
              pyochain.abc._mixins.Fluent[Fluent]
              pyochain.abc._mixins.Pipe[Pipe]
              pyochain.abc._mixins.Tap[Tap]

                              pyochain.abc._iterator.PyoIterator --> pyochain.core._iterators.Peekable
                                pyochain.abc._iterable.PyoIterable --> pyochain.abc._iterator.PyoIterator
                                pyochain.abc._mixins.Checkable --> pyochain.abc._iterable.PyoIterable
                
                pyochain.abc._mixins.Fluent --> pyochain.abc._iterable.PyoIterable
                                pyochain.abc._mixins.Pipe --> pyochain.abc._mixins.Fluent
                
                pyochain.abc._mixins.Tap --> pyochain.abc._mixins.Fluent
                





              click pyochain.core._iterators.Peekable href "" "pyochain.core._iterators.Peekable"
              click pyochain.abc._iterator.PyoIterator href "" "pyochain.abc._iterator.PyoIterator"
              click pyochain.abc._iterable.PyoIterable href "" "pyochain.abc._iterable.PyoIterable"
              click pyochain.abc._mixins.Checkable href "" "pyochain.abc._mixins.Checkable"
              click pyochain.abc._mixins.Fluent href "" "pyochain.abc._mixins.Fluent"
              click pyochain.abc._mixins.Pipe href "" "pyochain.abc._mixins.Pipe"
              click pyochain.abc._mixins.Tap href "" "pyochain.abc._mixins.Tap"
            
Source code in pyochain/core/_iterators.pyi
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
168
169
170
171
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
@final
class Peekable[T](PyoIterator[T]):
    @override
    def __iter__(self) -> Self: ...
    @override
    def __next__(self) -> T: ...
    def __bool__(self) -> bool: ...
    def peek(self) -> Option[T]:
        """Returns the `next()` value without advancing the `Iterator`.

        Returns:
            Option[T]: The next value wrapped in `Some(T)` if available, or `NONE` if the iteration is over.

        Examples:
            Peek at the next value of an iterator without consuming it.
            ```python
            from pyochain import Range, Some

            iterator = Range(5).iter().peekable()

            # Peek at the first item of the iterator without consuming it.
            assert iterator.peek() == Some(0)

            # The next item returned is still 0, as we haven't consumed it yet.
            assert iterator.next() == Some(0)

            # Now the next item returned is 1, as we have consumed the first item.
            assert iterator.next() == Some(1)
            ```
        """
    def next_if(self, func: Callable[[T], bool]) -> Option[T]:
        """Consume and return the next value of this iterator if a condition is `True`.

        Args:
            func (Callable[[T], bool]): A function that takes the next value and returns a boolean.

        Returns:
            Option[T]: The next value wrapped in `Some(T)` if the condition is true, or `NONE` if the condition is false or the iteration is over.

        Examples:
            Consume a number if it's equal to 0.
            ```python
            from pyochain import Range, Some

            iterator = Range(5).iter().peekable()

            # The first item of the iterator is 0; consume it.
            assert iterator.next_if(lambda x: x == 0) == Some(0)

            # The next item returned is now 1, so `next_if` will return `None`.
            assert iterator.next_if(lambda x: x == 0).is_none()

            # `next_if` retains the next item if the predicate evaluates to `false` for it.
            assert iterator.next() == Some(1)
            ```
            Consume any number less than 10.
            ```python
            iterator = Range(1, 20).iter().peekable()

            # Consume all numbers less than 10
            while iterator.next_if(lambda x: x < 10).is_some():
                pass

            # The next value returned will be 10
            assert iterator.next() == Some(10)
            ```
        """
    def next_if_eq(self, expected: object) -> Option[T]:
        """Return the next item if it is equal to expected.

        Args:
            expected (object): The value to compare the next item against.

        Returns:
            Option[T]: The next value wrapped in `Some(T)` if it is equal to expected, or `NONE` if it is not equal or the iteration is over.

        Example:
            Consume a number if it's equal to 0.
            ```python
            from pyochain import Range, Some

            iterator = Range(5).iter().peekable()

            # The first item of the iterator is 0; consume it.
            assert iterator.next_if_eq(0) == Some(0)

            # The next item returned is now 1, so `next_if_eq` will return `None`.
            assert iterator.next_if_eq(0).is_none()

            # `next_if_eq` retains the next item if it was not equal to `expected`.
            assert iterator.next() == Some(1)
            ```
        """

    def next_if_map[S, R](
        self: Peekable[S], f: Callable[[S], Result[R, S]]
    ) -> Option[R]:
        """Consumes the next value of this `Iterator` and applies a function *f* on it, returning the result if the closure returns `Ok`.

        Otherwise if the closure returns `Err` the value is put back for the next iteration.

        The content of the `Err` variant is typically the original value of the closure, but this is not required.

        If a different value is returned, the next `peek()` or `next()` call will result in this new value.

        Args:
            f (Callable[[S], Result[R, S]]): A function that takes the next value and returns a Result.

        Returns:
            Option[R]: The result of the function wrapped in `Some(R)` if the function returns `Ok(R)`, or `NONE` if the function returns `Err(S)` or the iteration is over.

        Examples:
            Parse the leading decimal number from an iterator of characters.
            ```python
            from pyochain import Iter, Option, Some, NONE, Result
            import unicodedata

            iterator = Iter("125 GOTO 10").peekable()
            line_num = 0

            def try_parse_digit(c: str) -> Result[int, str]:
                try:
                    res = Some(unicodedata.digit(c))
                except ValueError as e:
                    res = NONE
                return res.ok_or(c)

            digit = iterator.next_if_map(try_parse_digit)
            while digit.is_some():
                line_num = line_num * 10 + digit.unwrap()
                digit = iterator.next_if_map(try_parse_digit)

            assert line_num == 125
            assert iterator.join("") == " GOTO 10"
            ```
        """

peek()

Returns the next() value without advancing the Iterator.

Returns:

Type Description
Option[T]

Option[T]: The next value wrapped in Some(T) if available, or NONE if the iteration is over.

Examples:

Peek at the next value of an iterator without consuming it.

from pyochain import Range, Some

iterator = Range(5).iter().peekable()

# Peek at the first item of the iterator without consuming it.
assert iterator.peek() == Some(0)

# The next item returned is still 0, as we haven't consumed it yet.
assert iterator.next() == Some(0)

# Now the next item returned is 1, as we have consumed the first item.
assert iterator.next() == Some(1)

Source code in pyochain/core/_iterators.pyi
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def peek(self) -> Option[T]:
    """Returns the `next()` value without advancing the `Iterator`.

    Returns:
        Option[T]: The next value wrapped in `Some(T)` if available, or `NONE` if the iteration is over.

    Examples:
        Peek at the next value of an iterator without consuming it.
        ```python
        from pyochain import Range, Some

        iterator = Range(5).iter().peekable()

        # Peek at the first item of the iterator without consuming it.
        assert iterator.peek() == Some(0)

        # The next item returned is still 0, as we haven't consumed it yet.
        assert iterator.next() == Some(0)

        # Now the next item returned is 1, as we have consumed the first item.
        assert iterator.next() == Some(1)
        ```
    """

next_if(func)

Consume and return the next value of this iterator if a condition is True.

Parameters:

Name Type Description Default
func Callable[[T], bool]

A function that takes the next value and returns a boolean.

required

Returns:

Type Description
Option[T]

Option[T]: The next value wrapped in Some(T) if the condition is true, or NONE if the condition is false or the iteration is over.

Examples:

Consume a number if it's equal to 0.

from pyochain import Range, Some

iterator = Range(5).iter().peekable()

# The first item of the iterator is 0; consume it.
assert iterator.next_if(lambda x: x == 0) == Some(0)

# The next item returned is now 1, so `next_if` will return `None`.
assert iterator.next_if(lambda x: x == 0).is_none()

# `next_if` retains the next item if the predicate evaluates to `false` for it.
assert iterator.next() == Some(1)
Consume any number less than 10.
iterator = Range(1, 20).iter().peekable()

# Consume all numbers less than 10
while iterator.next_if(lambda x: x < 10).is_some():
    pass

# The next value returned will be 10
assert iterator.next() == Some(10)

Source code in pyochain/core/_iterators.pyi
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
168
169
170
171
172
173
def next_if(self, func: Callable[[T], bool]) -> Option[T]:
    """Consume and return the next value of this iterator if a condition is `True`.

    Args:
        func (Callable[[T], bool]): A function that takes the next value and returns a boolean.

    Returns:
        Option[T]: The next value wrapped in `Some(T)` if the condition is true, or `NONE` if the condition is false or the iteration is over.

    Examples:
        Consume a number if it's equal to 0.
        ```python
        from pyochain import Range, Some

        iterator = Range(5).iter().peekable()

        # The first item of the iterator is 0; consume it.
        assert iterator.next_if(lambda x: x == 0) == Some(0)

        # The next item returned is now 1, so `next_if` will return `None`.
        assert iterator.next_if(lambda x: x == 0).is_none()

        # `next_if` retains the next item if the predicate evaluates to `false` for it.
        assert iterator.next() == Some(1)
        ```
        Consume any number less than 10.
        ```python
        iterator = Range(1, 20).iter().peekable()

        # Consume all numbers less than 10
        while iterator.next_if(lambda x: x < 10).is_some():
            pass

        # The next value returned will be 10
        assert iterator.next() == Some(10)
        ```
    """

next_if_eq(expected)

Return the next item if it is equal to expected.

Parameters:

Name Type Description Default
expected object

The value to compare the next item against.

required

Returns:

Type Description
Option[T]

Option[T]: The next value wrapped in Some(T) if it is equal to expected, or NONE if it is not equal or the iteration is over.

Example

Consume a number if it's equal to 0.

from pyochain import Range, Some

iterator = Range(5).iter().peekable()

# The first item of the iterator is 0; consume it.
assert iterator.next_if_eq(0) == Some(0)

# The next item returned is now 1, so `next_if_eq` will return `None`.
assert iterator.next_if_eq(0).is_none()

# `next_if_eq` retains the next item if it was not equal to `expected`.
assert iterator.next() == Some(1)

Source code in pyochain/core/_iterators.pyi
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
199
def next_if_eq(self, expected: object) -> Option[T]:
    """Return the next item if it is equal to expected.

    Args:
        expected (object): The value to compare the next item against.

    Returns:
        Option[T]: The next value wrapped in `Some(T)` if it is equal to expected, or `NONE` if it is not equal or the iteration is over.

    Example:
        Consume a number if it's equal to 0.
        ```python
        from pyochain import Range, Some

        iterator = Range(5).iter().peekable()

        # The first item of the iterator is 0; consume it.
        assert iterator.next_if_eq(0) == Some(0)

        # The next item returned is now 1, so `next_if_eq` will return `None`.
        assert iterator.next_if_eq(0).is_none()

        # `next_if_eq` retains the next item if it was not equal to `expected`.
        assert iterator.next() == Some(1)
        ```
    """

next_if_map(f)

Consumes the next value of this Iterator and applies a function f on it, returning the result if the closure returns Ok.

Otherwise if the closure returns Err the value is put back for the next iteration.

The content of the Err variant is typically the original value of the closure, but this is not required.

If a different value is returned, the next peek() or next() call will result in this new value.

Parameters:

Name Type Description Default
f Callable[[S], Result[R, S]]

A function that takes the next value and returns a Result.

required

Returns:

Type Description
Option[R]

Option[R]: The result of the function wrapped in Some(R) if the function returns Ok(R), or NONE if the function returns Err(S) or the iteration is over.

Examples:

Parse the leading decimal number from an iterator of characters.

from pyochain import Iter, Option, Some, NONE, Result
import unicodedata

iterator = Iter("125 GOTO 10").peekable()
line_num = 0

def try_parse_digit(c: str) -> Result[int, str]:
    try:
        res = Some(unicodedata.digit(c))
    except ValueError as e:
        res = NONE
    return res.ok_or(c)

digit = iterator.next_if_map(try_parse_digit)
while digit.is_some():
    line_num = line_num * 10 + digit.unwrap()
    digit = iterator.next_if_map(try_parse_digit)

assert line_num == 125
assert iterator.join("") == " GOTO 10"

Source code in pyochain/core/_iterators.pyi
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
def next_if_map[S, R](
    self: Peekable[S], f: Callable[[S], Result[R, S]]
) -> Option[R]:
    """Consumes the next value of this `Iterator` and applies a function *f* on it, returning the result if the closure returns `Ok`.

    Otherwise if the closure returns `Err` the value is put back for the next iteration.

    The content of the `Err` variant is typically the original value of the closure, but this is not required.

    If a different value is returned, the next `peek()` or `next()` call will result in this new value.

    Args:
        f (Callable[[S], Result[R, S]]): A function that takes the next value and returns a Result.

    Returns:
        Option[R]: The result of the function wrapped in `Some(R)` if the function returns `Ok(R)`, or `NONE` if the function returns `Err(S)` or the iteration is over.

    Examples:
        Parse the leading decimal number from an iterator of characters.
        ```python
        from pyochain import Iter, Option, Some, NONE, Result
        import unicodedata

        iterator = Iter("125 GOTO 10").peekable()
        line_num = 0

        def try_parse_digit(c: str) -> Result[int, str]:
            try:
                res = Some(unicodedata.digit(c))
            except ValueError as e:
                res = NONE
            return res.ok_or(c)

        digit = iterator.next_if_map(try_parse_digit)
        while digit.is_some():
            line_num = line_num * 10 + digit.unwrap()
            digit = iterator.next_if_map(try_parse_digit)

        assert line_num == 125
        assert iterator.join("") == " GOTO 10"
        ```
    """