Skip to content

Instantly share code, notes, and snippets.

@Blaisorblade
Last active June 11, 2019 22:30
Show Gist options
  • Save Blaisorblade/af8ec3cb3a02bee3c92afcad0e2126c9 to your computer and use it in GitHub Desktop.
Save Blaisorblade/af8ec3cb3a02bee3c92afcad0e2126c9 to your computer and use it in GitHub Desktop.
Immutable circular list, adapted from https://stackoverflow.com/a/8374217/53974
object Init {
class Circular[A](val value: A, getter: => Circular[A]) {
lazy val get: Circular[A] = getter
}
def create[A](as: Traversable[A]): Circular[A] = {
def go[A](as: Traversable[A], initTail: => Circular[A]): Circular[A] = {
if (as.nonEmpty)
new Circular(as.head, go(as.tail, initTail))
else
initTail
}
lazy val b: Circular[A] = go(as, b)
b
}
def prepend[A](a: A, as: Circular[A]): Circular[A] = {
def go[A](as: Circular[A], origTail: Circular[A], initTail: => Circular[A]): Circular[A] = {
if (as != origTail)
new Circular(as.value, go(as.get, origTail, initTail))
else
initTail
}
lazy val b: Circular[A] = new Circular(a, new Circular(as.value, go(as.get, as, b)))
b
}
def take[A](n: Int)(xs: Circular[A]): List[A] =
if (n == 0)
Nil
else
xs.value :: take(n - 1)(xs.get)
def main(xs: Array[String]): Unit = {
val as1 = create(List(1, 2, 3))
println(take(15)(as1))
val as2 = prepend(0, as1)
println(take(15)(as2))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment