function prod(*a) if len(a)==0 return iter([[]]) else return [x]+t for x in a[0] for t in prod(*a[1..]) end end function permutations(a) a = list(a) return fn*|| if len(a)<=1 yield copy(a) else x = a[..0] for p in permutations(a[1..]) for i in len(a) yield p[..i-1]+x+p[i..] end end end end end function combinations(a,k) a = list(a) n = len(a) return fn*|| if k>n then return empty end indices = list(k) yield list(a[i] for i in indices) while true finish = true for i in k-1..0: -1 if indices[i] != i+n-k finish = false break end end if finish then return empty end indices[i] += 1 for j in i+1..k-1 indices[j] = indices[j-1]+1 end yield list(a[i] for i in indices) end end end function accumulate(a,f,g=null) if g is null i = iter(a) return fn*|| y = i() yield y for x in i y = f(y,x) yield y end end else y = f f = g return fn*|| yield y for x in a y = f(y,x) yield y end end end end function chain(*argv) return fn*|| for a in argv for x in a yield x end end end end function repeat(x,n=null) if n is null return fn*|| while true yield x end end else return fn*|| for i in n yield x end end end end Iterable.step = fn step|m| i = iter(self) n = m-1 return fn*|| while true yield i() for k in n do i() end end end end