非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

自由モノイドのイテレーター(7)

自由モノイドプログラミング言語の作成(Python版 2)

自由モノイドのクラス

「自由モノイドのイテレーター」では、自由モノイドを表すクラスを作成して、それを無限の場合に拡張しようとしていました。自由モノイド元は有限個の生成元の積なのでそうしていたのですが、最初から無限個の積としてもできそうだということがわかってきました。これは Python でもできるということがわかりました。Python 版では無限個の積を表すクラスを作成します。有限個の積の場合は自由モノイドの元となります。

from itertools import chain
from typing import Callable, Generic, Iterable, Iterator, TypeVar

T = TypeVar('T')

class FreeMonoid(Generic[T], Iterable[T]):
	def __init__(self, iterobj: Iterable[T]):
		self.elements: Iterator[T] = iter(iterobj)
	def __iter__(self):
		return self
	def __next__(self) -> T:
		return next(self.elements)
	def __and__(self, nextmon: "FreeMonoid[T]") -> "FreeMonoid[T]":
		return FreeMonoid[T](chain(self, nextmon))
	@classmethod
	def unit(cls, item: T) -> "FreeMonoid[T]":
		return FreeMonoid([item])
	@classmethod
	def zero(cls) -> "FreeMonoid[T]":
		return FreeMonoid([])
	def zip_with(self, func: Callable[[T, T], T], mon2: Iterable[T]) -> "FreeMonoid[T]":
		def zip_with_iter(func: Callable[[T, T], T], mon1: Iterable[T], mon2: Iterable[T]) -> Iterable[T]:
			for x, y in zip(mon1, mon2):
				yield func(x, y)
		return FreeMonoid(zip_with_iter(func, self, mon2))
	def tail(self) -> "FreeMonoid[T]":
		def tail_iter(mon: "FreeMonoid[T]") -> Iterable[T]:
			istail = False
			for x in mon:
				if istail:
					yield x
				istail = True
		return FreeMonoid(tail_iter(self))