Skip to content

Instantly share code, notes, and snippets.

@Centaur
Last active December 19, 2016 04:34
Show Gist options
  • Save Centaur/96771ea0cff73d620aaf6f1b6d2d240c to your computer and use it in GitHub Desktop.
Save Centaur/96771ea0cff73d620aaf6f1b6d2d240c to your computer and use it in GitHub Desktop.
Tailrec to Fold
package org.snippets
import scala.collection.immutable.Stream.#::
import scala.util.{Failure, Success, Try}
class InsufficientParametersException(message: String) extends RuntimeException(message)
object Tailrec2Fold {
type RpnModel = String
type CalculationState = (String, String)
def calculate(model: RpnModel, first: String, second: String): CalculationState = {
println("Confirm short circuit:" + (model, first, second))
if (model == "m5") {
throw new InsufficientParametersException("Error")
} else ("[" + model + "-" + first, ":" + second + "-" + model + "]")
}
def loop(rpnModels: List[RpnModel], state: CalculationState): CalculationState = {
rpnModels match {
case Nil => state
case head :: tail =>
try {
loop(tail, calculate(head, state._1, state._2))
} catch {
case ex: InsufficientParametersException => println(ex.getMessage); state
}
}
}
def loopFold(rpnModels: List[RpnModel], state: CalculationState): CalculationState = {
def folder: List[Try[CalculationState]] = rpnModels.foldLeft(Try(state) :: Nil) { (accu, nextModel) =>
accu match {
case Success(s) :: _ => Try(calculate(nextModel, s._1, s._2)) :: accu
case Failure(e) :: tail => println(e.getMessage); return tail
}
}
folder.head.get
}
def loopStream(rpnModels: List[RpnModel], state: CalculationState): CalculationState = {
lazy val stateStream:Stream[Try[CalculationState]] = Success(state) #:: stateStream.zip(rpnModels).map {
case (Success(s), model) => Try(calculate(model, s._1, s._2))
}
stateStream.takeWhile(_.isSuccess).last.get
}
val modelSuccess = List("m1", "m2", "m3", "m4")
val modelFailure = List("m1", "m5", "m3", "m4")
val stateFixture: CalculationState = ("s1", "s2")
def main(args: Array[String]): Unit = {
assert(loop(modelSuccess, stateFixture) == loopFold(modelSuccess, stateFixture))
println("===================")
assert(loop(modelFailure, stateFixture) == loopFold(modelFailure, stateFixture))
println("===================")
assert(loop(modelSuccess, stateFixture) == loopStream(modelSuccess, stateFixture))
println("===================")
assert(loop(modelFailure, stateFixture) == loopStream(modelFailure, stateFixture))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment