Source code for monad.types.list

# -*- coding: utf-8 -*-
# Copyright (c) 2012-2014, Philip Xu <pyx@xrefactor.com>
# License: BSD New, see LICENSE for details.
"""monad.types.list - The List Monad."""

from collections import Sequence
from itertools import chain

from . import LazySequence, MonadPlus
from ..mixins import Ord


[docs]class List(MonadPlus, Ord, Sequence): """The List Monad. Representing nondeterministic computation. >>> List(42) List(42) >>> List(1, 2, 3) List(1, 2, 3) >>> List([]) List([]) >>> List.from_iterable(range(3)) List(0, 1, 2) >>> List.from_iterable(n for n in (1, 2, 3) if n % 2 == 0) List(2) >>> List(List(2)) List(List(2)) Lists are lazy >>> from itertools import count >>> m = List.from_iterable(count()) >>> m[:5] List(0, 1, 2, 3, 4) >>> m[520:524] List(520, 521, 522, 523) >>> list(m[1000:1002]) [1000, 1001] Bind operation with ``>>`` >>> spawn = lambda cell: List(cell, cell) >>> spawn('c') List('c', 'c') >>> spawn('c') >> spawn List('c', 'c', 'c', 'c') >>> grow = lambda cell: List(cell + '~') >>> grow('o') List('o~') >>> grow('o') >> grow >> grow >> grow List('o~~~~') >>> generation = lambda cell: grow(cell) + spawn(cell) >>> first = List('o') >>> first List('o') >>> first >> generation List('o~', 'o', 'o') >>> first >> generation >> generation List('o~~', 'o~', 'o~', 'o~', 'o', 'o', 'o~', 'o', 'o') """ # pylint: disable = too-many-ancestors def __init__(self, *items): super(List, self).__init__(LazySequence(items)) def __getitem__(self, index): items = self.value.__getitem__(index) if isinstance(index, slice): return self.from_iterable(items) return items def __len__(self): return len(self.value) def __nonzero__(self): return len(self.value) def __repr__(self): """Customized Show.""" return 'List({})'.format(', '.join(repr(x) for x in self))
[docs] @classmethod def from_iterable(cls, iterator): """Creates ``List`` from iterable.""" instance = cls.unit() instance.value = LazySequence(iterator) return instance
[docs] def fmap(self, function): """fmap of List Monad.""" return self.from_iterable(function(i) for i in self)
[docs] def join(self): """join of List Monad.""" return self.from_iterable(chain.from_iterable(self))
[docs] def plus(self, monad): """plus operation, concatenates two ``List``.""" if not isinstance(monad, type(self)): return NotImplemented return self.from_iterable(chain(self, monad))
List.zero = List()