Skip to content

Instantly share code, notes, and snippets.

@Ghurtchu
Last active October 19, 2022 12:40
Show Gist options
  • Save Ghurtchu/3a754e9c4b52ad7a443cecca049f0fa2 to your computer and use it in GitHub Desktop.
Save Ghurtchu/3a754e9c4b52ad7a443cecca049f0fa2 to your computer and use it in GitHub Desktop.
Here's to the lazy ones...
enum Stream[+A]:
case Empty
case Cons(h: () => A, t: () => Stream[A])
def headOption: Option[A] = this match
case Empty => None
case Cons(h, t) => Some(h())
def filter(f: A => Boolean): Stream[A] = this match
case Empty => Empty
case Cons(h, t) if f(h()) => Cons(h, () => t().filter(f))
case Cons(h, t) if !f(h()) => t().filter(f)
def toList: List[A] = this match
case Empty => Nil
case Cons(h, t) => h() :: t().toList
def tail: Stream[A] = this match
case Empty => Empty
case Cons(h, t) => t()
def head: A = this match
case Empty => throw UnsupportedOperationException()
case Cons(h, t) => h()
def take(n: Int): Stream[A] =
@tailrec
def loop(index: Int, originalStream: Stream[A], newStream: Stream[A]): Stream[A] =
if index == n then newStream
else loop(index + 1, originalStream.tail, Cons(() => originalStream.head, () => newStream))
loop(0, this, Empty)
def drop(n: Int): Stream[A] = this match
case Empty => Empty
case Cons(h, t) if n == 0 => Cons(h, t)
case Cons(h, t) if n != 0 => t().drop(n - 1)
def exists(p: A => Boolean): Boolean = this match
case Cons(h, t) => p(h()) || t().exists(p)
case _ => false
object Stream:
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] =
lazy val head = hd
lazy val tail = tl
Cons(() => head, () => tail)
def empty[A]: Stream[A] = Empty
def apply[A](as: A*): Stream[A] = if as.isEmpty then empty else cons(as.head, apply(as.tail: _*))
@Ghurtchu
Copy link
Author

Oh you're so lazy..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment