Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 23, 2017 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yasuabe/9c51826aea6102a32c8d734833873343 to your computer and use it in GitHub Desktop.
Save yasuabe/9c51826aea6102a32c8d734833873343 to your computer and use it in GitHub Desktop.
Scala version of Prob Monad (from LYAHFGG)
object ProbInstances {
implicit def probMonad: Monad[Prob] = new Monad[Prob] {
def flatMap[A, B](pa: Prob[A])(f: A => Prob[B]): Prob[B] = pa flatMap f
def tailRecM[A, B](a: A)(f: A => Prob[Either[A, B]]): Prob[B] = {
val buf = List.newBuilder[(B, Rational)]
@tailrec def go(pes: List[(Prob[Either[A, B]], Rational)]): Unit = pes match {
case (Prob(e :: es), r0) :: tail => e match {
case (Right(b), r) => buf += (b -> r * r0) ; go(Prob(es) -> r0 :: tail)
case (Left(a2), r) => go(f(a2) -> r :: Prob(es) -> r :: tail)
}
case (Prob(Nil), _) :: tail => go(tail)
case Nil => ()
}
go(pure(f(a)).es)
Prob(buf.result)
}
override def pure[A](a: A): Prob[A] = Prob(List(a -> Rational(1, 1)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment