自由モノイドプログラミング言語の作成(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))





