import scala.language.higherKinds import scalaz._ import Scalaz._ import iteratee._ import iteratee.Input._ import iteratee.Iteratee._ import scalaz.std.iterable._ object Run extends App { // sample using State monad def sampleI[A](k: Int): Iteratee[A, Vector[A]] = sampleI[A](k, 0, Vector()) private def sampleI[A](k: Int, n: Int, sample: Vector[A]): Iteratee[A, Vector[A]] = cont[A, Id, Vector[A]]((c: Input[A]) => c match { case Element(x) => sampleI(k, n + 1, algorithmR(k, n + 1, sample, x)) case _ => done(sample, Empty[A]) }) val rand = new scala.util.Random() def algorithmR[A](k: Int, n: Int, sample: Vector[A], x: A): Vector[A] = { if (sample.size < k) { sample :+ x // must keep first k elements } else { val r = rand.nextInt(n) + 1 // for simplicity, rand is global/stateful if (r <= k) sample.updated(r - 1, x) // sample is 0-index else sample } } { print((sampleI(10) &= EnumeratorT.enumStream((Short.MinValue to Short.MaxValue).toStream) ).run) } }