I am going through the following Shift/Reset tutorial: http://www.is.ocha.ac.jp/~asai/cw2011tutorial/main-e.pdf.
I got pretty good results so far in translating the OchaCaml examples to Scala (all the way up to section 2.11). But now I seem to have hit a wall. The code from the paper from Asai/Kiselyov defines the following recursive function (this is OchaCaml - I think):
(* a_normal : term_t => term_t *)
let rec a_normal term = match term with
Var (x) -> Var (x)
| Lam (x, t) -> Lam (x, reset (fun () -> a_normal t))
| App (t1, t2) ->
shift (fun k ->
let t = gensym () in (* generate fresh variable *)
App (Lam (t, (* let expression *)
k (Var (t))), (* continue with new variable *)
App (a_normal t1, a_normal t2))) ;;
The function is supposed to A-normalize a lambda expression. This is my Scala translation:
// section 2.11
object ShiftReset extends App {
sealed trait Term
case class Var(x: String) extends Term
case class Lam(x: String, t: Term) extends Term
case class App(t1: Term, t2: Term) extends Term
val gensym = {
var i = 0
() => { i += 1; "t" + i }
}
def a_normal(t: Term): Term#cps[Term] = t match {
case Var(x) => Var(x)
case Lam(x, t) => Lam(x, reset(a_normal(t)))
case App(t1, t2) => shift{ (k:Term=>Term) =>
val t = gensym()
val u = Lam(t, k(Var(t)))
val v = App(a_normal(t1), a_normal(t2))
App(u, v): Term
}
}
}
I am getting the following compilation error:
found : ShiftReset.Term #scala.util.continuations.cpsSynth
#scala.util.continuations.cpsParam[ShiftReset.Term,ShiftReset.Term]
required: ShiftReset.Term
case App(t1, t2) => shift{ (k:Term=>Term) =>
^
one error found
I think the plugin is telling me that it cannot deal with nested shift... Is there a way to make the code compile (either a basic error I've overlooked or some workaround)? I have tried to convert the pattern match to a if/else if/else and to introduce more local variables but I got the same error.
Alternately, would I have more luck using Haskell and the Cont monad (+ the shift/reset from here) or is there going to be the same type of limitation with nested shift? I am adding the Haskell tag as well, since I don't mind switching to Haskell to go through the rest of the tutorial.
Edit: Thanks to James who figured out which line the continuation plugin could not deal with and how to tweak it, it now works. Using the version in his answer and the following formatting code:
def format(t: Term): String = t match {
case Var(x) => s"$x"
case Lam(x, t) => s"\\$x.${format(t)}"
case App(Lam(x, t1), t2) => s"let $x = ${format(t2)} in ${format(t1)}"
case App(Var(x), Var(y)) => s"$x$y"
case App(Var(x), t2) => s"$x (${format(t2)})"
case App(t1, t2) => s"(${format(t1)}) (${format(t2)})"
}
I get the output that the paper mentions (though I don't grasp yet how the continuation actually manages it):
sCombinator:
\x.\y.\z.(xz) (yz)
reset{a_normal(sCombinator)}:
\x.\y.\z.let t1 = xz in let t2 = yz in let t3 = t1t2 in t3
The problem is the line:
val v = App(a_normal(t1), a_normal(t2))
I'm not certain, but I think the type inferencer is getting confused by the fact that a_normal returns a Term#cps[Term], but we're inside a shift so the continuation isn't annotated the same way.
It will compile if you pull the line up out of the shift block:
def a_normal(t: Term): Term#cps[Term] = t match {
case Var(x) => Var(x)
case Lam(x, t) => Lam(x, reset(a_normal(t)))
case App(t1, t2) =>
val v = App(a_normal(t1), a_normal(t2))
shift{ (k:Term=>Term) =>
val t = gensym()
val u = Lam(t, k(Var(t)))
App(u, v): Term
}
}
Regarding nested shifts in general, you can definitely do this if each nested continuation has a compatible type:
object NestedShifts extends App {
import scala.util.continuations._
def foo(x: Int): Int#cps[Unit] = shift { k: (Int => Unit) =>
k(x)
}
reset {
val x = foo(1)
println("x: " + x)
val y = foo(2)
println("y: " + y)
val z = foo(foo(3))
println("z: " + z)
}
}
This program prints to stdout:
x: 1
y: 2
z: 3
Related
i have a question about the Parser in Scala. I'll just post the important part here so that there would not be too much codes. For the eval Function:
def eval(t: Term): Double = t match {
case Addition(l, r) => eval(l) + eval(r)
case Multiplication(l, r) => eval(l) * eval(r)
case Numeric(i) => i
case Variable("X") => 3
}
And the calculate function:
def calculate(arg: String): Double = {
return eval(parseAll(term, arg).get)
}
now i should overload the function "calculate" so that it takes an extra Parameter tup : (String, Double) and assign the value for this String. For example ("Y",2) then Y = 2 in the Parser. And then calculate the parser. But i don't know how to assign the value for this String. I had a stupid idea and tried this but it didn't work.
def calculate(arg: String, tup : (String, Double)) : Double = {
tup match {
case (a,b) => {
def eval(t : Term): Double = t match {
case Variable(a) => b
}
return eval(parseAll(term, arg).get)
}
}
can you guys pls help me out ? Thank you !!
You're almost there, you just need to tell the compiler that the a in your Variable pattern is actually the a from your (a, b) pattern. By default, what you do is called shadowing of the variable name a (in the scope of this pattern match, a is the value extracted in Variable, and the other a is forgotten).
What you want is something like
...
case Variable(`a`) => b
...
or, if your expression gets a little more complicated, you should rather use a guard:
...
case Variable(v) if v == a => b
...
EDIT However, now your eval function is not well defined. You need to put it all at once:
def eval(t: Term, varAssignement: (String, Double)): Double = t match {
case Addition(l, r) => eval(l) + eval(r)
case Multiplication(l, r) => eval(l) * eval(r)
case Numeric(i) => i
case Variable(a) if a == varAssignment._1 => varAssignment._2
}
Or, if you want to have multiple variables:
def eval(t: Term, assignments: Map[String, Double]): Double = t match {
case Addition(l, r) => eval(l) + eval(r)
case Multiplication(l, r) => eval(l) * eval(r)
case Numeric(i) => i
case Variable(a) if assignments.exists(a) => assignments(a)
}
Beware that you'll still get MatchErrors whenever an unassigned variable is used.
So I got something like this:
abstract class Term
case class App(f:Term,x:Term) extends Term
case class Var(s:String) extends Term
case class Amb(a:Term, b:Term) extends Term //ambiguity
And a Term may look like this:
App(Var(f),Amb(Var(x),Amb(Var(y),Var(z))))
So what I need is all variations that are indicated by the Amb class.
This is used to represent a ambiguous parse forest and I want to type check each possible variation and select the right one.
In this example I would need:
App(Var(f),Var(x))
App(Var(f),Var(y))
App(Var(f),Var(z))
Whats the best way to create these variations in scala?
Efficiency would be nice, but is not really requirement.
If possible I like to refrain from using reflection.
Scala provides pattern matching solve these kinds of problems. A solution would look like:
def matcher(term: Term): List[Term] = {
term match {
case Amb(a, b) => matcher(a) ++ matcher(b)
case App(a, b) => for { va <- matcher(a); vb <- matcher(b) } yield App(va, vb)
case v: Var => List(v)
}
}
You can do this pretty cleanly with a recursive function that traverses the tree and expands ambiguities:
sealed trait Term
case class App(f: Term, x: Term) extends Term
case class Var(s: String) extends Term
case class Amb(a: Term, b: Term) extends Term
def det(term: Term): Stream[Term] = term match {
case v: Var => Stream(v)
case App(f, x) => det(f).flatMap(detf => det(x).map(App(detf, _)))
case Amb(a, b) => det(a) ++ det(b)
}
Note that I'm using a sealed trait instead of an abstract class in order to take advantage of the compiler's ability to check exhaustivity.
It works as expected:
scala> val app = App(Var("f"), Amb(Var("x"), Amb(Var("y"), Var("z"))))
app: App = App(Var(f),Amb(Var(x),Amb(Var(y),Var(z))))
scala> det(app) foreach println
App(Var(f),Var(x))
App(Var(f),Var(y))
App(Var(f),Var(z))
If you can change the Term API, you could more or less equivalently add a def det: Stream[Term] method there.
Since my abstract syntax is fairly large (and I have multiple) and I tried my luck with Kiama.
So here is the version Travis Brown and Mark posted with Kiama.
Its not pretty, but I hope it works. Comments are welcome.
def disambiguateRule: Strategy = rule {
case Amb(a: Term, b: Term) =>
rewrite(disambiguateRule)(a).asInstanceOf[List[_]] ++
rewrite(disambiguateRule)(b).asInstanceOf[List[_]]
case x =>
val ch = getChildren(x)
if(ch.isEmpty) {
List(x)
}
else {
val chdis = ch.map({ rewrite(disambiguateRule)(_) }) // get all disambiguate children
//create all combinations of the disambiguated children
val p = combinations(chdis.asInstanceOf[List[List[AnyRef]]])
//use dup from Kiama to recreate the term with every combination
val xs = for { newchildren <- p } yield dup(x.asInstanceOf[Product], newchildren.toArray)
xs
}
}
def combinations(ll: List[List[AnyRef]]): List[List[AnyRef]] = ll match {
case Nil => Nil
case x :: Nil => x.map { List(_) }
case x :: xs => combinations(xs).flatMap({ ys => x.map({ xx => xx :: ys }) })
}
def getChildren(x: Any): List[Any] = {
val l = new ListBuffer[Any]()
all(queryf {
case a => l += a
})(x)
l.toList
}
Is there a syntax in Scala that allows extractors to take a customization argument? This example is a bit contrived. Suppose I have a binary search tree on integers, and I want to match on the current node if its value is divisible by some custom value.
Using F# active patterns, I can do the following:
type Tree =
| Node of int * Tree * Tree
| Empty
let (|NodeDivisibleBy|_|) x t =
match t with
| Empty -> None
| Node(y, l, r) -> if y % x = 0 then Some((l, r)) else None
let doit = function
| NodeDivisibleBy(2)(l, r) -> printfn "Matched two: %A %A" l r
| NodeDivisibleBy(3)(l, r) -> printfn "Matched three: %A %A" l r
| _ -> printfn "Nada"
[<EntryPoint>]
let main args =
let t10 = Node(10, Node(1, Empty, Empty), Empty)
let t15 = Node(15, Node(1, Empty, Empty), Empty)
doit t10
doit t15
0
In Scala, I can do something similar, but not quite what I want:
sealed trait Tree
case object Empty extends Tree
case class Node(v: Int, l: Tree, r: Tree) extends Tree
object NodeDivisibleBy {
def apply(x: Int) = new {
def unapply(t: Tree) = t match {
case Empty => None
case Node(y, l, r) => if (y % x == 0) Some((l, r)) else None
}
}
}
def doit(t: Tree) {
// I would prefer to not need these two lines.
val NodeDivisibleBy2 = NodeDivisibleBy(2)
val NodeDivisibleBy3 = NodeDivisibleBy(3)
t match {
case NodeDivisibleBy2(l, r) => println("Matched two: " + l + " " + r)
case NodeDivisibleBy3(l, r) => println("Matched three: " + l + " " + r)
case _ => println("Nada")
}
}
val t10 = Node(10, Node(1, Empty, Empty), Empty)
val t15 = Node(15, Node(1, Empty, Empty), Empty)
doit(t10)
doit(t15)
It would be great if I could do:
case NodeDivisibleBy(2)(l, r) => println("Matched two: " + l + " " + r)
case NodeDivisibleBy(3)(l, r) => println("Matched three: " + l + " " + r)
but this is a compile time error: '=>' expected but '(' found.
Thoughts?
From the spec:
SimplePattern ::= StableId ‘(’ [Patterns] ‘)’
An extractor pattern x(p1, ..., pn) where n ≥ 0 is of the same
syntactic form as a constructor pattern. However, instead of a case
class, the stable identifier x denotes an object which has a member
method named unapply or unapplySeq that matches the pattern.
and:
A stable identifier is a path which ends in an identifier.
i.e., not an expression like NodeDivisibleBy(2).
So no, this isn't possible in any straightforward way in Scala, and personally I think that's just fine: having to write the following (which by the way I'd probably define in the NodeDivisibleBy object and import):
val NodeDivisibleBy2 = NodeDivisibleBy(2)
val NodeDivisibleBy3 = NodeDivisibleBy(3)
is a small price to pay for the increased readability of not having to decipher arbitrary expressions in the case clause.
As Travis Brown has noted, it's not really possible in scala.
What I do in that scenario is just separating the decomposition from the test with a guard and an alias.
val DivisibleBy = (n: Node, x: Int) => (n.v % x == 0)
def doit(t: Tree) = t match {
case n # Node(y, l, r) if DivisibleBy(n,2) => println("Matched two: " + l + " " + r)
case n # Node(y, l, r) if DivisibleBy(n,3) => println("Matched three: " + l + " " + r)
case _ => println("Nada")
}
Defining a separate DivisibleBy is obviously complete overkill in this simple case, but may help readability in more complex scenarios in a similar way as F# active patterns do.
You could also define divisibleBy as a method of Node and have:
case class Node(v: Int, l: Tree, r: Tree) extends Tree {
def divisibleBy(o:Int) = (v % o)==0
}
def doit(t: Tree) = t match {
case n # Node(y, l, r) if n divisibleBy 2 => println("Matched two: " + l + " " + r)
case n # Node(y, l, r) if n divisibleBy 3 => println("Matched three: " + l + " " + r)
case _ => println("Nada")
}
which I think is more readable (if more verbose) than the F# version
Bind together the case class, predicate and arguments, then match on the result as usual.
case class Foo(i: Int)
class Testable(val f: Foo, val ds: List[Int])
object Testable {
def apply(f: Foo, ds: List[Int]) = new Testable(f, ds)
def unapply(t: Testable): Option[(Foo, List[Int])] = {
val xs = t.ds filter (t.f.i % _ == 0)
if (xs.nonEmpty) Some((t.f, xs)) else None
}
}
object Test extends App {
val f = Foo(100)
Testable(f, List(3,5,20)) match {
case Testable(f, 3 :: Nil) => println(s"$f matched three")
case Testable(Foo(i), 5 :: Nil) if i < 50
=> println(s"$f matched five")
case Testable(f, ds) => println(s"$f matched ${ds mkString ","}")
case _ => println("Nothing")
}
}
Late answer, but there is a scalac plugin providing syntax ~(extractorWithParam(p), bindings), with all safety from compilation: https://github.com/cchantep/acolyte/tree/master/scalac-plugin#match-component
As I know answer is no.
I also use the previous way for this case.
I have an immutable data structure where I have nested values in Maps, like so:
case class TradingDay(syms: Map[String, SymDay] = Map.empty)
case class SymDay(sym: String, traders: Map[String, TraderSymDay] = Map.empty)
case class TraderSymDay(trader: String, sym: String, trades: List[Trade] = Nil)
Separately I have a list of all trades over the day, and I want to generate the TradingDay structure, where
case class Trade(sym: String, trader: String, qty: Int)
I am trying to figure out how I would update this structure with lenses (see appendix) by folding through my trades:
(TradingDay() /: trades) { (trd, d) =>
def sym = trd.sym
def trader = trd.trader
import TradingDay._
import SymDay._
import TraderSymDay._
val mod =
for {
_ <- (Syms member sym).mods(
_ orElse some(SymDay(sym)))
_ <- (Syms at sym andThen Traders member trader).mods(
_ orElse some(TraderSymDay(trader, sym)))
_ <- (Syms at sym andThen (Traders at trader) andThen Trades).mods(
trd :: _)
x <- init
} yield x
mod ! d
}
This works; but I'm wondering whether I could be less repetitive (in terms of adding to a map and then modifying the value at the key of a map. It doesn't seem that much less annoying than the associated deep-copy.
Appendix - the lenses
object TradingDay {
val Syms = Lens[TradingDay, Map[String, SymDay]](_.syms, (d, s) => d.copy(syms = s))
}
object SymDay {
val Traders = Lens[SymDay, Map[String, TraderSymDay]](_.traders, (d, t) => d.copy(traders = t))
}
object TraderSymDay {
val Trades = Lens[TraderSymDay, List[Trade]](_.trades, (d, f) => d.copy(trades = f))
}
with
type #>[A,B] = Lens[A, B]
and by keeping this lens
val Syms : Lens[TradingDay, Map[String, SymDay]]
and defining those lenses:
val F : Map[String, SymDay] #> Option[SymDay] = ...
val G : Option[SymDay] #> Map[String, TraderSymDay] = ...
val H : Map[String, TraderSymDay] #> Option[TraderSymDay] = ...
val I : Option[TraderSymDay] #> List[Trade] = ...
val J: TradingDay #> List[Trade] = Syms >=> F >=> G >=> H >=> I
you could get this:
(trades /: TradingDay()){ (trd, d) => (J.map(trd :: _).flatMap(_ => init)) ! d }
Answer provided by Jordan West (#_jrwest)
It's only a slight change and involves introducing the following conversion:
implicit def myMapLens[S,K,V] = MyMapLens[S,K,V](_)
case class MyMapLens[S,K,V](lens: Lens[S,Map[K,V]]) {
def putIfAbsent(k: K, v: => V)
= lens.mods(m => m get k map (_ => m) getOrElse (m + (k -> v)))
}
Then we can use this as follows:
(TradingDay() /: trades) { (d, trade) =>
def sym = trade.sym
def trader = trade.trader
def traders = Syms at sym andThen Traders
def trades = Syms at sym andThen (Traders at trader) andThen Trades
val upd =
for {
_ <- Syms putIfAbsent (sym, SymDay(sym))
_ <- traders putIfAbsent (trader, TraderSymDay(trader, sym))
_ <- trades.mods(trade :: _)
} yield ()
upd ~> d
}
I am trying to avoid constructs like this:
val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result
Ok, in this example the then and else branch are simple, but you can image complex ones.
I built the following:
object TernaryOp {
class Ternary[T](t: T) {
def is[R](bte: BranchThenElse[T,R]) = if (bte.branch(t)) bte.then(t) else bte.elze(t)
}
class Branch[T](branch: T => Boolean) {
def ?[R] (then: T => R) = new BranchThen(branch,then)
}
class BranchThen[T,R](val branch: T => Boolean, val then: T => R)
class Elze[T,R](elze: T => R) {
def :: (bt: BranchThen[T,R]) = new BranchThenElse(bt.branch,bt.then,elze)
}
class BranchThenElse[T,R](val branch: T => Boolean, val then: T => R, val elze: T => R)
implicit def any2Ternary[T](t: T) = new Ternary(t)
implicit def fct2Branch[T](branch: T => Boolean) = new Branch(branch)
implicit def fct2Elze[T,R](elze: T => R) = new Elze(elze)
}
Defined that, I can replace the above simple example with:
this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}
But how can I get rid of the s: String =>? I want something like that:
this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}
I guess the compiler needs the extra stuff to infer types.
From Tony Morris' Lambda Blog:
I hear this question a lot. Yes it does. Instead of c ? p : q, it is
written if(c) p else q.
This may not be preferable. Perhaps you’d like to write it using the
same syntax as Java. Sadly, you can’t. This is because : is not a
valid identifier. Fear not, | is! Would you settle for this?
c ? p | q
Then you’ll need the following code. Notice the call-by-name (=>)
annotations on the arguments. This evaluation strategy is required to
correctly rewrite Java’s ternary operator. This cannot be done in Java
itself.
case class Bool(b: Boolean) {
def ?[X](t: => X) = new {
def |(f: => X) = if(b) t else f
}
}
object Bool {
implicit def BooleanBool(b: Boolean) = Bool(b)
}
Here is an example using the new operator that we just defined:
object T { val condition = true
import Bool._
// yay!
val x = condition ? "yes" | "no"
}
Have fun ;)
We can combine How to define a ternary operator in Scala which preserves leading tokens? with the answer to Is Option wrapping a value a good pattern? to get
scala> "Hi".getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res0: String = String
scala> List.getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res1: String = List
Is this adequate for your needs?
Rex Kerr’s answer expressed in basic Scala:
"Hi".getClass.getSimpleName match {
case x if x.endsWith("$") => x.init
case x => x
}
although I’m not sure what part of the if–else construct you want to optimise.
Since if-else constructions in Scala return a value, you can use this
val a = if (1 < 0) 1 else 2
More info: https://alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples
Since : by itself won't be a valid operator unless you are ok with always escaping it with back ticks :, you could go with another character, e.g. "|" as in one of the answers above. But how about elvis with a goatee ?::
implicit class Question[T](predicate: => Boolean) {
def ?(left: => T) = predicate -> left
}
implicit class Colon[R](right: => R) {
def ::[L <% R](pair: (Boolean, L)): R = if (q._1) q._2 else right
}
val x = (5 % 2 == 0) ? 5 :: 4.5
Of course this again won't work if you values are lists, since they have :: operator themselves.