Range Over Iterators in Miranda

Explanation

In this exercise, we will learn how to use Python iterators to range over various elements. Just like the original language supports iterators, Python also has robust support for iterators and generator functions. Each example will be adapted to Python and will cover creating custom iterators, using them for iteration, and even generating infinite sequences like Fibonacci numbers.

Example Code

class Element:
    def __init__(self, val, next=None):
        self.val = val
        self.next = next

class List:
    def __init__(self):
        self.head = None
        self.tail = None

    def push(self, value):
        new_elem = Element(value)
        if self.tail:
            self.tail.next = new_elem
        else:
            self.head = new_elem
        self.tail = new_elem

    def all(self):
        current = self.head
        while current:
            yield current.val
            current = current.next

def gen_fib():
    a, b = 1, 1
    while True:
        yield a
        a, b = b, a + b

def main():
    lst = List()
    lst.push(10)
    lst.push(13)
    lst.push(23)

    for e in lst.all():
        print(e)

    all_elements = list(lst.all())
    print(f'all: {all_elements}')

    for n in gen_fib():
        if n >= 10:
            break
        print(n)

if __name__ == '__main__':
    main()

Explanation

  1. List and Element Classes: Similar to the original List[T] and element[T] types, we define Element and List classes in Python. Element mimics a node in a linked list, and List manages the nodes.

  2. push Method: This method adds new elements to the list. If the list is empty (tail is None), it initializes the head and tail to the new element. Otherwise, it adds the new element to the end of the list.

  3. all Method: This method is an iterator in Python which yields all the elements in the list. It uses the yield keyword to return elements one by one, similar to the iterator function pattern in the previous language.

  4. gen_fib Function: This function generates Fibonacci numbers indefinitely. It uses a while True loop to yield Fibonacci numbers until the external n >= 10 condition breaks the loop.

  5. main Function: This function demonstrates how to use the custom list and Fibonacci generator. It first creates a list and adds elements to it. It then iterates over all the elements in the list using the all method and collects all elements into a list for printing. Finally, it generates and prints Fibonacci numbers, stopping when a number reaches or exceeds 10.

How to Run

To run this program, save it to a file (e.g., iterators_example.py) and execute it using Python.

$ python iterators_example.py

Output:

10
13
23
all: [10, 13, 23]
1
1
2
3
5
8

This concludes the example of how we can use iterators and generators in Python to achieve similar functionality as in the original language.