Can scala syntatic sugar make a congruence mod n? - scala

Consider 2+7 == 3+6 (mod 5). Can you some how use scala syntactic sugar to achieve the same in scala code?
Keep in mind that 2+7 and 3+6 are regular scala Int so overriding the + or == to be mod 5 doesn't work. I'm actually interested in more complex congruences on algebras A. I could do A.congruent(a,b), and write that with some nice symbols like A.~(a,b), but I am interested in a == b (A) or a ==(A) b or perhaps A(a == b). Something where the congruence appears inbetween the terms a and b.
The bottom line of my struggles is that the congruence is defined for type A, and a,b are some elements passed to A but not actually of type A. E.g. A might be a group of matrices and the congruence is if individual matrices a and b differ by a scalar i.e. a*b^-1=sI_n. In particular, a, b will live inside of many groups and the congruence will change based on that. So I it isn't possible to simply add a reference within a and b back to A.
Some how the right solution seems to be the mathematical one, label the equivalence with A not the variables a and b. Yet scala syntactic sugar may not have such a sweetness in mind. Any suggestions appreciated.

Try this:
implicit class ModEquals(a: Int) {
def %%(n: Int) = new { def ===(b: Int) = (a - b) % n == 0 }
}
Usage:
7 %% 3 === 10
This solution enriches Ints with a %% method that takes the congruence. In this example, it's just modulu, but this can easily be extended to anything. The returned object is a class that has an === method defined to implements the equality check.

import scala.languageFeature.implicitConversions
import scala.languageFeature.reflectiveCalls
case class ModuloArg(list: List[Int]) {
assert(list.size > 1)
def ==%%?(m: Int) = {
val hm = list.head % m
list.tail.filter(i => (i % m) != hm).isEmpty
}
def ::%%(n: Int) = ModuloArg(n :: list)
}
implicit class ModuloArgOps(i: Int) {
def ::%%(n: Int) = ModuloArg(n :: i :: Nil)
}
Now, you can use these to check modulo equality,
// 4 == 10 (mod 3)
scala> val mod3Equal4And10 = 4 ::%% 10 ==%%? 3
// mod3Equal4And10: Boolean = true
// 4 == 11 (mod 3)
scala> val mod3Equal4And11 = 4 ::%% 11 ==%%? 3
//mod3Equal4And11: Boolean = false
// 4 == 10 == 13 == 16 (mod 3)
scala> val mod3Equal4And10And13And16 = 4 ::%% 10 ::%% 13 ::%% 16 ==%%? 3
// mod3Equal4And10And13And16: Boolean = true

Related

Equality function for pair components

Is there a function in Scala that compares the two components of a pair for equality? Something like:
def pairEquals[A, B](pair: Pair[A, B]): Boolean = (pair._1 == pair._2)
In Haskell, that would be:
uncurry (==)
There is nothing like that in the standard library. But you can easily extend Pairs to have your behaviour
implicit class PimpedTuple[A,B](tp: Tuple2[A,B]) {
def pairEquals = tp._1 == tp._2
}
val x = (2, 3)
x.pairEquals // false
val y = (1, 1)
y.pairEquals // true
Edit:
Another way to do it would be: x == x.swap
Edit2:
Here is a third way which plays around with the equals function and uses a similar construct as the uncurry in haskell.
// This is necessary as there is no globally available function to compare values
def ===(a:Any, b: Any) = a == b
val x = (1,1)
(===_).tupled(x) // true

Convert normal recursion to tail recursion

I was wondering if there is some general method to convert a "normal" recursion with foo(...) + foo(...) as the last call to a tail-recursion.
For example (scala):
def pascal(c: Int, r: Int): Int = {
if (c == 0 || c == r) 1
else pascal(c - 1, r - 1) + pascal(c, r - 1)
}
A general solution for functional languages to convert recursive function to a tail-call equivalent:
A simple way is to wrap the non tail-recursive function in the Trampoline monad.
def pascalM(c: Int, r: Int): Trampoline[Int] = {
if (c == 0 || c == r) Trampoline.done(1)
else for {
a <- Trampoline.suspend(pascal(c - 1, r - 1))
b <- Trampoline.suspend(pascal(c, r - 1))
} yield a + b
}
val pascal = pascalM(10, 5).run
So the pascal function is not a recursive function anymore. However, the Trampoline monad is a nested structure of the computation that need to be done. Finally, run is a tail-recursive function that walks through the tree-like structure, interpreting it, and finally at the base case returns the value.
A paper from RĂșnar Bjanarson on the subject of Trampolines: Stackless Scala With Free Monads
In cases where there is a simple modification to the value of a recursive call, that operation can be moved to the front of the recursive function. The classic example of this is Tail recursion modulo cons, where a simple recursive function in this form:
def recur[A](...):List[A] = {
...
x :: recur(...)
}
which is not tail recursive, is transformed into
def recur[A]{...): List[A] = {
def consRecur(..., consA: A): List[A] = {
consA :: ...
...
consrecur(..., ...)
}
...
consrecur(...,...)
}
Alexlv's example is a variant of this.
This is such a well known situation that some compilers (I know of Prolog and Scheme examples but Scalac does not do this) can detect simple cases and perform this optimisation automatically.
Problems combining multiple calls to recursive functions have no such simple solution. TMRC optimisatin is useless, as you are simply moving the first recursive call to another non-tail position. The only way to reach a tail-recursive solution is remove all but one of the recursive calls; how to do this is entirely context dependent but requires finding an entirely different approach to solving the problem.
As it happens, in some ways your example is similar to the classic Fibonnaci sequence problem; in that case the naive but elegant doubly-recursive solution can be replaced by one which loops forward from the 0th number.
def fib (n: Long): Long = n match {
case 0 | 1 => n
case _ => fib( n - 2) + fib( n - 1 )
}
def fib (n: Long): Long = {
def loop(current: Long, next: => Long, iteration: Long): Long = {
if (n == iteration)
current
else
loop(next, current + next, iteration + 1)
}
loop(0, 1, 0)
}
For the Fibonnaci sequence, this is the most efficient approach (a streams based solution is just a different expression of this solution that can cache results for subsequent calls). Now,
you can also solve your problem by looping forward from c0/r0 (well, c0/r2) and calculating each row in sequence - the difference being that you need to cache the entire previous row. So while this has a similarity to fib, it differs dramatically in the specifics and is also significantly less efficient than your original, doubly-recursive solution.
Here's an approach for your pascal triangle example which can calculate pascal(30,60) efficiently:
def pascal(column: Long, row: Long):Long = {
type Point = (Long, Long)
type Points = List[Point]
type Triangle = Map[Point,Long]
def above(p: Point) = (p._1, p._2 - 1)
def aboveLeft(p: Point) = (p._1 - 1, p._2 - 1)
def find(ps: Points, t: Triangle): Long = ps match {
// Found the ultimate goal
case (p :: Nil) if t contains p => t(p)
// Found an intermediate point: pop the stack and carry on
case (p :: rest) if t contains p => find(rest, t)
// Hit a triangle edge, add it to the triangle
case ((c, r) :: _) if (c == 0) || (c == r) => find(ps, t + ((c,r) -> 1))
// Triangle contains (c - 1, r - 1)...
case (p :: _) if t contains aboveLeft(p) => if (t contains above(p))
// And it contains (c, r - 1)! Add to the triangle
find(ps, t + (p -> (t(aboveLeft(p)) + t(above(p)))))
else
// Does not contain(c, r -1). So find that
find(above(p) :: ps, t)
// If we get here, we don't have (c - 1, r - 1). Find that.
case (p :: _) => find(aboveLeft(p) :: ps, t)
}
require(column >= 0 && row >= 0 && column <= row)
(column, row) match {
case (c, r) if (c == 0) || (c == r) => 1
case p => find(List(p), Map())
}
}
It's efficient, but I think it shows how ugly complex recursive solutions can become as you deform them to become tail recursive. At this point, it may be worth moving to a different model entirely. Continuations or monadic gymnastics might be better.
You want a generic way to transform your function. There isn't one. There are helpful approaches, that's all.
I don't know how theoretical this question is, but a recursive implementation won't be efficient even with tail-recursion. Try computing pascal(30, 60), for example. I don't think you'll get a stack overflow, but be prepared to take a long coffee break.
Instead, consider using a Stream or memoization:
val pascal: Stream[Stream[Long]] =
(Stream(1L)
#:: (Stream from 1 map { i =>
// compute row i
(1L
#:: (pascal(i-1) // take the previous row
sliding 2 // and add adjacent values pairwise
collect { case Stream(a,b) => a + b }).toStream
++ Stream(1L))
}))
The accumulator approach
def pascal(c: Int, r: Int): Int = {
def pascalAcc(acc:Int, leftover: List[(Int, Int)]):Int = {
if (leftover.isEmpty) acc
else {
val (c1, r1) = leftover.head
// Edge.
if (c1 == 0 || c1 == r1) pascalAcc(acc + 1, leftover.tail)
// Safe checks.
else if (c1 < 0 || r1 < 0 || c1 > r1) pascalAcc(acc, leftover.tail)
// Add 2 other points to accumulator.
else pascalAcc(acc, (c1 , r1 - 1) :: ((c1 - 1, r1 - 1) :: leftover.tail ))
}
}
pascalAcc(0, List ((c,r) ))
}
It does not overflow the stack but as on big row and column but Aaron mentioned it's not fast.
Yes it's possible. Usually it's done with accumulator pattern through some internally defined function, which has one additional argument with so called accumulator logic, example with counting length of a list.
For example normal recursive version would look like this:
def length[A](xs: List[A]): Int = if (xs.isEmpty) 0 else 1 + length(xs.tail)
that's not a tail recursive version, in order to eliminate last addition operation we have to accumulate values while somehow, for example with accumulator pattern:
def length[A](xs: List[A]) = {
def inner(ys: List[A], acc: Int): Int = {
if (ys.isEmpty) acc else inner(ys.tail, acc + 1)
}
inner(xs, 0)
}
a bit longer to code, but i think the idea i clear. Of cause you can do it without inner function, but in such case you should provide acc initial value manually.
I'm pretty sure it's not possible in the simple way you're looking for the general case, but it would depend on how elaborate you permit the changes to be.
A tail-recursive function must be re-writable as a while-loop, but try implementing for example a Fractal Tree using while-loops. It's possble, but you need to use an array or collection to store the state for each point, which susbstitutes for the data otherwise stored in the call-stack.
It's also possible to use trampolining.
It is indeed possible. The way I'd do this is to
begin with List(1) and keep recursing till you get to the
row you want.
Worth noticing that you can optimize it: if c==0 or c==r the value is one, and to calculate let's say column 3 of the 100th row you still only need to calculate the first three elements of the previous rows.
A working tail recursive solution would be this:
def pascal(c: Int, r: Int): Int = {
#tailrec
def pascalAcc(c: Int, r: Int, acc: List[Int]): List[Int] = {
if (r == 0) acc
else pascalAcc(c, r - 1,
// from let's say 1 3 3 1 builds 0 1 3 3 1 0 , takes only the
// subset that matters (if asking for col c, no cols after c are
// used) and uses sliding to build (0 1) (1 3) (3 3) etc.
(0 +: acc :+ 0).take(c + 2)
.sliding(2, 1).map { x => x.reduce(_ + _) }.toList)
}
if (c == 0 || c == r) 1
else pascalAcc(c, r, List(1))(c)
}
The annotation #tailrec actually makes the compiler check the function
is actually tail recursive.
It could be probably be further optimized since given that the rows are symmetric, if c > r/2, pascal(c,r) == pascal ( r-c,r).. but left to the reader ;)

Do macros make naturally chained comparisons possible in Scala?

Scala does not provide chained comparisons as Python does:
// Python:
0 < x <= 3
// Scala:
0 < x && x <= 3
Will Scala 2.10 with the new macro feature enable the programmer write a library that adds this feature? Or is this beyond the scope of Scala's macros?
Macros seem to be the right choice for the implementation of such syntactic sugar as they do not complicate the parser/compiler.
You don't need macros for it:
class ChainedComparisons[T : Ordering](val res: Boolean, right: T) {
def <^ (next: T) = new ChainedComparisons(res && Ordering[T].lt(right, next), next)
def <=^ (next: T) = new ChainedComparisons(res && Ordering[T].lteq(right, next), next)
}
implicit def chainedComparisonsToBoolean(c: ChainedComparisons[_]) = c.res
class StartChainedComparisons[T : Ordering](left: T) {
def <^(right: T) = new ChainedComparisons(Ordering[T].lt(left, right), right)
def <=^(right: T) = new ChainedComparisons(Ordering[T].lteq(left, right), right)
}
implicit def toStartChainedComparisons[T : Ordering](left: T) = new StartChainedComparisons(left)
Usage:
scala> val x = 2
x: Int = 2
scala> 1 <^ x : Boolean
res0: Boolean = true
scala> 1 <^ x <^ 3 : Boolean
res1: Boolean = true
scala> 1 <^ x <^ 2 : Boolean
res2: Boolean = false
scala> 1 <^ x <=^ 2 : Boolean
res3: Boolean = true
scala> if (1 <^ x <^ 3) println("true") else println(false)
true
scala> 1 <=^ 1 <^ 2 <=^ 5 <^ 10 : Boolean
res5: Boolean = true
I don't think Scala macros will help here... (and please correct me if I'am wrong, Eugene will certainly check this)
Macros can only be applied on a type-checked AST (and produce also a type-checked AST). Here the problem is that the expression:
0 < x <= 3
Will be evaluate to: (see another post)
((0 < x) <= 3) // type error
and there no such function <=(i: Int) in Boolean.
I don't see a way to make this expression compiling, thus macros are helpless.
Of course you could use a custom class to achieve your goal, but without macros (I could give you an example if needed), a possible syntax could be 0 less x lesseq 3 or x between (0, 3)

Updating a 2d table of counts

Suppose I want a Scala data structure that implements a 2-dimensional table of counts that can change over time (i.e., individual cells in the table can be incremented or decremented). What should I be using to do this?
I could use a 2-dimensional array:
val x = Array.fill[Int](1, 2) = 0
x(1)(2) += 1
But Arrays are mutable, and I guess I should slightly prefer immutable data structures.
So I thought about using a 2-dimensional Vector:
val x = Vector.fill[Int](1, 2) = 0
// how do I update this? I want to write something like val newX : Vector[Vector[Int]] = x.add((1, 2), 1)
// but I'm not sure how
But I'm not sure how to get a new vector with only a single element changed.
What's the best approach?
Best depends on what your criteria are. The simplest immutable variant is to use a map from (Int,Int) to your count:
var c = (for (i <- 0 to 99; j <- 0 to 99) yield (i,j) -> 0).toMap
Then you access your values with c(i,j) and set them with c += ((i,j) -> n); c += ((i,j) -> (c(i,j)+1)) is a little bit annoying, but it's not too bad.
Faster is to use nested Vectors--by about a factor of 2 to 3, depending on whether you tend to re-set the same element over and over or not--but it has an ugly update method:
var v = Vector.fill(100,100)(0)
v(82)(49) // Easy enough
v = v.updated(82, v(82).updated(49, v(82)(49)+1) // Ouch!
Faster yet (by about 2x) is to have only one vector which you index into:
var u = Vector.fill(100*100)(0)
u(82*100 + 49) // Um, you think I can always remember to do this right?
u = u.updated(82*100 + 49, u(82*100 + 49)+1) // Well, that's actually better
If you don't need immutability and your table size isn't going to change, just use an array as you've shown. It's ~200x faster than the fastest vector solution if all you're doing is incrementing and decrementing an integer.
If you want to do this in a very general and functional (but not necessarily performant) way, you can use lenses. Here's an example of how you could use Scalaz 7's implementation, for example:
import scalaz._
def at[A](i: Int): Lens[Seq[A], A] = Lens.lensg(a => a.updated(i, _), (_(i)))
def at2d[A](i: Int, j: Int) = at[Seq[A]](i) andThen at(j)
And a little bit of setup:
val table = Vector.tabulate(3, 4)(_ + _)
def show[A](t: Seq[Seq[A]]) = t.map(_ mkString " ") mkString "\n"
Which gives us:
scala> show(table)
res0: String =
0 1 2 3
1 2 3 4
2 3 4 5
We can use our lens like this:
scala> show(at2d(1, 2).set(table, 9))
res1: String =
0 1 2 3
1 2 9 4
2 3 4 5
Or we can just get the value at a given cell:
scala> val v: Int = at2d(2, 3).get(table)
v: Int = 5
Or do a lot of more complex things, like apply a function to a particular cell:
scala> show(at2d(2, 2).mod(((_: Int) * 2), table))
res8: String =
0 1 2 3
1 2 3 4
2 3 8 5
And so on.
There isn't a built-in method for this, perhaps because it would require the Vector to know that it contains Vectors, or Vectors or Vectors etc, whereas most methods are generic, and it would require a separate method for each number of dimensions, because you need to specify a co-ordinate arg for each dimension.
However, you can add these yourself; the following will take you up to 4D, although you could just add the bits for 2D if that's all you need:
object UpdatableVector {
implicit def vectorToUpdatableVector2[T](v: Vector[Vector[T]]) = new UpdatableVector2(v)
implicit def vectorToUpdatableVector3[T](v: Vector[Vector[Vector[T]]]) = new UpdatableVector3(v)
implicit def vectorToUpdatableVector4[T](v: Vector[Vector[Vector[Vector[T]]]]) = new UpdatableVector4(v)
class UpdatableVector2[T](v: Vector[Vector[T]]) {
def updated2(c1: Int, c2: Int)(newVal: T) =
v.updated(c1, v(c1).updated(c2, newVal))
}
class UpdatableVector3[T](v: Vector[Vector[Vector[T]]]) {
def updated3(c1: Int, c2: Int, c3: Int)(newVal: T) =
v.updated(c1, v(c1).updated2(c2, c3)(newVal))
}
class UpdatableVector4[T](v: Vector[Vector[Vector[Vector[T]]]]) {
def updated4(c1: Int, c2: Int, c3: Int, c4: Int)(newVal: T) =
v.updated(c1, v(c1).updated3(c2, c3, c4)(newVal))
}
}
In Scala 2.10 you don't need the implicit defs and can just add the implicit keyword to the class definitions.
Test:
import UpdatableVector._
val v2 = Vector.fill(2,2)(0)
val r2 = v2.updated2(1,1)(42)
println(r2) // Vector(Vector(0, 0), Vector(0, 42))
val v3 = Vector.fill(2,2,2)(0)
val r3 = v3.updated3(1,1,1)(42)
println(r3) // etc
Hope that's useful.

Implementing NPlusK patterns in Scala

I thought I could implement n+k patterns as an active pattern in scala via unapply, but it seems to fail with unspecified value parameter: k
object NPlusK {
def apply(n : Int, k : Int) = {
n + k
}
def unapply(n : Int, k : Int) = {
if (n > 0 && n > k) Some(n - k) else None
}
}
object Main {
def main(args: Array[String]): Unit = {
}
def fac(n: Int) : BigInt = {
n match {
case 0 => 1
case NPlusK(n, 1) => n * fac(n - 1)
}
}
}
Is it possible to implement n+k patterns in Scala and in that event how?
You should look at this question for a longer discussion, but here's a short adaptation for your specific case.
An unapply method can only take one argument, and must decide from that argument how to split it into two parts. Since there are multiple ways to divide some integer x into n and k such that x = n + k, you can't use an unapply for this.
You can get around it by creating a separate extractors for each k. Thus, instead of NplusK you'd have Nplus1, Nplus2, etc since there is exactly one way to get n from x such that x = n + 1.
case class NplusK(k: Int) {
def unapply(n: Int) = if (n > 0 && n > k) Some(n - k) else None
}
val Nplus1 = NplusK(1)
val Nplus1(n) = 5 // n = 4
So your match becomes:
n match {
case 0 => 1
case Nplus1(n) => n * fac(n - 1)
}
Deconstructor unapply does not work this way at all. It takes only one argument, the matched value, and returns an option on a tuple, with as many elements as there are arguments to the your pattern (NPlusK). That is, when you have
(n: Int) match {
...
case NPlusK(n, 1)
It will look for an unapply method with an Int (or supertype) argument. If there is such a method, and if the return type is a Tuple2 (as NPlusK appears with two arguments in the pattern), then it will try to match. Whatever subpattern there are inside NPlusK (here the variable n, and the constant 1), will not be passed to unapply in anyway (what do you expect if you write case NPlusK(NPlusK(1, x), NPlusK(1, y))?). Instead, if unapply returns some tuple, then each element of the tuple will be matched to the corresponding subpattern, here n which always matches, and 1 which will match if the value is equal to 1.
You could write
def unapply(n: Int) = if (n > 0) Some((n-1, 1)) else None.
That would match when your NPlusK(n, 1). But that would not match NPlusK(n, 2), nor NPlusK(1, n) (except if n is 2). This does not make much sense. A pattern should probably have only one possible match. NPlusK(x, y) can match n in many different ways.
What would work would be something Peano integers like, with Succ(n) matching n+1.