Skip to content

Instantly share code, notes, and snippets.

@sshark
Created November 1, 2022 16:44
Show Gist options
  • Save sshark/d51cb8d1ca45b9bcbdcd54f2f5f9cc1c to your computer and use it in GitHub Desktop.
Save sshark/d51cb8d1ca45b9bcbdcd54f2f5f9cc1c to your computer and use it in GitHub Desktop.
package org.teckhooi.fp.dojo2.fpis.iostream
import org.teckhooi.fp.dojo2.fpis.iostream.Process.{Await, Emit, Halt}
sealed trait Process[I, O] {
import Process._
def apply(s: LazyList[I]): LazyList[O] = this match {
case Halt() => LazyList()
case Emit(head, tail) => head #:: tail.apply(s)
case Await(recv) =>
s match {
case h #:: t => recv(Some(h))(t)
case xs => recv(None)(xs)
}
}
def repeat: Process[I, O] = {
def go(p: Process[I, O]): Process[I, O] = p match {
case Halt() => go(this)
case Emit(head, tail) => Emit(head, go(tail))
case Await(recv) =>
Await {
case None => recv(None)
case x => go(recv(x))
}
}
go(this)
}
}
object Process {
case class Emit[I, O](head: O, tail: Process[I, O] = Halt[I, O]()) extends Process[I, O]
case class Await[I, O](recv: Option[I] => Process[I, O]) extends Process[I, O]
case class Halt[I, O]() extends Process[I, O]
}
object RunMe extends App {
def liftOne[I, O](f: I => O): Process[I, O] =
Await {
case Some(x) => Emit(f(x))
case _ => Halt()
}
val i = liftOne((i: Int) => i * 2).repeat(LazyList(1, 2, 3)).toList
println(i.mkString(","))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment