You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jun 23, 2020. It is now read-only.
"playground" should "eval amb via delimited continuations" in {
import scala.util.continuations._
case class Cont[T, U](fn: T => U, arg: T)
class Evaluator[T, U](init: Cont[T, U]) {
var queue = Queue.empty[Cont[Any, U]]
var results = Vector.empty[U]
lazy val eval: Vector[U] = {
queue.enqueue(init)
loop()
results
}
def amb[V](vs: Vector[V]): V @cpsParam[U, Unit] = {
shift {
k: (V => U) =>
vs.foreach {
v =>
queue.enqueue(Cont[V, U](k, v))
}
}
}
@tailrec
private def loop(): Unit = {
if (queue.nonEmpty) {
val (cont, newQueue) = queue.dequeue
queue = newQueue
reset {
val result = cont.fn(cont.arg)
results = results :+ result
}
loop()
}
}
}
}
Not sure what to do next...
The text was updated successfully, but these errors were encountered:
The shift/reset-style continuations here are different from the call/cc-style continuations at the link. The Ruby version used an explicit vector of backtrack points, because calling the continuation means "abort", and the stack was used for normal flow-control. The Scala version is pretty much the opposite. The stack contains the backtracking information in a sequence of calls to amb, and communication between amb and the caller is done via the continuations. You were using reset entirely wrong. The reset goes around the shifts (the shifts can be bare, or inside other functions), and it limits how much of a continuation they can capture. You didn't put a shift inside the reset, breaking it.
The whole class Amb dance is because type inference is absolutely atrocious with this plugin. You'll have to do things like Ret to actually use amb:
valnums= (1 to 5).toList
println(reset {
typeRet= (Int, Int)
Some((amb[Ret](nums), amb[Ret](nums)))
.filter { case (a, b) =>valx= a + b; x * x ==8* x }
})
// more like the Ruby version
println(reset {
typeRet= (Int, Int)
vall= amb[Ret](nums)
valr= amb[Ret](nums)
valx= l + r
Some(amb[Ret](if(x * x ==8* x) List((l, r)) elseNil))
})
You might want to try passing a type parameter to the resets. Sometimes having an expected type eliminates the need to give explicit parameters elsewhere.
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Experimenting on implementing http://www.randomhacks.net/2005/10/11/amb-operator via delimited continuations in Scala. Getting:
The code attempt:
Not sure what to do next...
The text was updated successfully, but these errors were encountered: