Created
March 10, 2017 10:35
-
-
Save rizsotto/d3f1b83a19765d545f2d1d828f5eb6a7 to your computer and use it in GitHub Desktop.
strange list fold with state monad
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scalaz.State | |
import scalaz._ | |
import Scalaz._ | |
sealed trait InputMsg{ | |
def id: Int | |
} | |
case class Started(id: Int) extends InputMsg | |
case class Stopped(id: Int) extends InputMsg | |
sealed trait OutputMsg | |
case class InProgress(id: Int) extends OutputMsg() | |
case class Finished(id: Int) extends OutputMsg | |
object Example { | |
type Stack = List[InputMsg] | |
def pop(pivot: InputMsg) = State[Stack, InputMsg] { state: Stack => | |
val (pair, rest) = state.partition(_.id == pivot.id) | |
(rest, pair.head) | |
} | |
def push(pivot: InputMsg) = State[Stack, Unit] { | |
case xs => (pivot :: xs, ()) | |
} | |
def handler(input: InputMsg): State[Stack, Option[OutputMsg]] = | |
input match { | |
case e@Started(id) => for { | |
_ <- push(e) | |
} yield None | |
case e@Stopped(id) => for { | |
_ <- pop(e) | |
} yield Some(Finished(id)) | |
} | |
def smash(input: List[InputMsg]): List[OutputMsg] = { | |
val initial = List[InputMsg]() | |
val (started, finished) = input.runTraverseS(initial)(handler) | |
finished.flatMap { | |
case Some(x) => List(x) | |
case None => List() | |
} ++ | |
started.map { | |
case Started(id) => InProgress(id) | |
} | |
} | |
def main(args: Array[String]): Unit = { | |
val input: List[InputMsg] = List(Started(1), Started(2), Stopped(1)) | |
//val expected: List[OutputMsg] = List(Finished(1), InProgress(2)) | |
println(s"input was: $input") | |
println(s"result is: ${smash(input)}") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment