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)
}
}