Skip to content

Instantly share code, notes, and snippets.

@mrkm4ntr
Last active August 29, 2015 14:21
Show Gist options
  • Save mrkm4ntr/ef6ec3371b32c9783c3f to your computer and use it in GitHub Desktop.
Save mrkm4ntr/ef6ec3371b32c9783c3f to your computer and use it in GitHub Desktop.
Reverse Polish Notation with Scalaz
import scalaz._
import Scalaz._
object RPN {
type DoubleListState[A] = State[List[Double], A]
def eval(input: String) = {
def binOp(op: String): Option[(Double, Double) => Double] = op match {
case "+" => Some(_ + _)
case "-" => Some(_ - _)
case "*" => Some(_ * _)
case "/" => Some(_ / _)
case _ => None
}
def read(t: String): OptionT[DoubleListState, Unit] =
t.parseDouble.toOption.fold(for {
op <- OptionT.optionT(binOp(t).point[DoubleListState])
s <- get[List[Double]].liftM[OptionT]
_ <- s match {
case i :: j :: xs => put[List[Double]](op(i, j) :: xs).liftM[OptionT]
case _ => OptionT.none[DoubleListState, Unit]
}
} yield ())(d => modify[List[Double]](d :: _).liftM[OptionT])
(for {
_ <- input.split(' ').toList.map(read _).sequenceU
r <- get[List[Double]].liftM[OptionT]
} yield r).run.evalZero[List[Double]].map(_.head)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment