Property definitions

combinations $ CartesianCollection :: defaultinit
# A view of a Cartesian-product collection over homogeneous collections.
#
# Therefore, this view *generates* all the sequences of elements constructed by associating
# en element for each one of the original collections.
#
# It is equivalent to doing nesting `for` for each collection.
#
# ~~~~
# var xs = [1, 2, 3]
# var ys = [8, 9]
# var xys = new CartesianCollection[Int]([xs, ys])
# assert xys.length == 6
# assert xys.to_a == [[1,8], [1,9], [2,8], [2,9], [3,8], [3,9]]
# ~~~~
#
# The pattern of the generate sequences produces a lexicographical order.
#
# Because it is a generator, it is memory-efficient and the sequences are created only when needed.
#
# Note: because it is a view, changes on the base collections are reflected on the view.
#
# ~~~~
# assert xs.pop == 3
# assert ys.pop == 9
# assert xys.to_a == [[1,8], [2,8]]
# ~~~~
class CartesianCollection[E]
	super Collection[SequenceRead[E]]

	# The base collections used to generate the sequences.
	var collections: SequenceRead[Collection[E]]

	redef fun length
	do
		var res = 1
		for c in collections do res = res * c.length
		return res
	end

	redef fun iterator do return new CartesianIterator[E](self)
end
lib/combinations/combinations.nit:76,1--116,3