Mix Scala Option and regular variable in a statement - scala

I would like to write conditional statements mixing transparently Scala Options and regular variables.
For example:
var o1 = Some(1)
var o2: Option[Int] = None
var x = 2
val test1 = x < 3 && o1<5 //=> should be true or Some(true)
val test2 = x < 3 && o2<5 //=> should be false or None
val test3 = x < 3 || o2<5 //=> should be true (o2 not evaluated)
of course I could write
test1 = x < 3 && o1.exists (_<5)
but I would prefer a cleaner syntax.
Any hint? Should I expand 'Option' with operators, or use implicits, or category theory or else?

What about mapping from Option[Int] to Option[Boolean]?
x < 3 && (o1 map {_ < 5} getOrElse false)
x < 3 && (o2 map {_ < 5} getOrElse false)
x < 3 || (o2 map {_ < 5} getOrElse false)

Using implicits is certainly easy:
implicit def enrichOptionInt(self: Option[Int]) = new {
def <(i: Int) = self.exists(_ < i)
}
val test1 = x < 3 && o1 < 5 // True
Or if you want it to work for any kind of Numeric:
class EnrichedOptionNumeric[N: Numeric](self: Option[N]) {
def <(n: N) = self.exists(v => implicitly[Numeric[N]].lt(v, n))
}
implicit def enrichOptionNumeric[N: Numeric](self: Option[N]) = new EnrichedOptionNumeric(self)
val oD = Some(2.0)
val test1 = x < 3 && o1 < 5 // true
val testD = x < 3 && oD < 5.0 // true
EDIT to answer question in comment:
If you want to support equality, you, unfortunately, cannot use == since that operator is already defined for Option. If a method (or operator) is already defined for a class, then the implicit will never be triggered since Scala only looks for implicits when it doesn't recognize the method being called.
You can however, simply define a different symbol to mean "option equals". For example, you could use ===. To do so, you'd just add the following line to the definition of EnrichedOptionNumeric above:
def ===(n: N) = self.exists(v => implicitly[Numeric[N]].equiv(v, n))
Then you can do:
val testE = x < 3 && o1 === 1 // true

Think about whether there's a more natural way to express the "missing" value in the context of this problem than using an Option. Maybe to say there's no limit, a Double with a value of Infinity would work, or an Int with Integer.MAX_VALUE. Then remove the Option from the problem completely. If you can't then you can use
var o1 = Some (1)
var o2 = Option[Int] = None
var x = 2
val test1 = x < 3 && o1.getOrElse(Integer.MAX_VALUE)<5 //=> should be true or Some(true)
val test2 = x < 3 && o2.getOrElse(Integer.MAX_VALUE)<5 //=> should be false or None
val test3 = x < 3 || o2.getOrElse(Integer.MAX_VALUE)<5 //=> should be true (o2 not evaluated)

Tomasz Nurkiewicz's answer can be made more succinct with some Scalaz sugar, and by employing the Monoid instance for Boolean.
The "zero" value for the monoid is false, so o getOrElse false becomes ~o, using a unary operator ~ defined in scalaz. (Here I am using scalaz 6.0.4)
def p: Int => Boolean = _ < 3
def q: Int => Boolean = _ < 5
import scalaz._, Scalaz._
scala> val test1 = p(x) && ~(o1 map q)
test1: Boolean = true
scala> val test2 = p(x) && ~(o2 map q)
test2: Boolean = false
scala> val test3 = p(x) || ~(o2 map q)
test3: Boolean = true

Scala can actually make an Ordering for Option[A] if you have an Ordering[A] but the semantics are different (None is the smallest value) from what you wanted.
Also, for the comparison to work, both values need to be of the same type, so you need a way to lift the Ints into an Option. I added an opt method for that purpose.
This is an example with the internal ordering:
import scala.math.Ordering.Implicits.infixOrderingOps
//This allows you to use method/operator syntax on anything with an Ordering
implicit def mkOption[A](a: A) = new { def opt: Option[A] = Some(a) }
var o1 = Some(1)
var o2: Option[Int] = None
var x = 2
val test1 = x < 3 && o1<5.opt //=> true
val test2 = x < 3 && o2<5.opt //=> true
val test3 = x < 3 || o2<5.opt //=> true
None > 0.opt //=> false
None < 0.opt //=> true
To get closer to your semantics, we can define a new ordering
implicit def mkOptionOrdering[A: Ordering] = new Ordering[Option[A]] {
def compare(a: Option[A], b: Option[A]): Int = {
if (a.isEmpty || b.isEmpty) 0
else implicitly[Ordering[A]].compare(a.get, b.get)
}
}
Now your tests will do what you expected and the 2 extra tests will also be false but those semantics are rather odd, compare returns 0 for things that aren't equal.

Related

SCALA: Generating a list of Tuple2 objects meeting some criteria

I want to generate a list of Tuple2 objects. Each tuple (a,b) in the list should meeting the conditions:a and b both are perfect squares,(b/30)<a<b
and a>N and b>N ( N can even be a BigInt)
I am trying to write a scala function to generate the List of Tuples meeting the above requirements?
This is my attempt..it works fine for Ints and Longs..But for BigInt there is sqrt problem I am facing..Here is my approach in coding as below:
scala> def genTups(N:Long) ={
| val x = for(s<- 1L to Math.sqrt(N).toLong) yield s*s;
| val y = x.combinations(2).map{ case Vector(a,b) => (a,b)}.toList
| y.filter(t=> (t._1*30/t._2)>=1)
| }
genTups: (N: Long)List[(Long, Long)]
scala> genTups(30)
res32: List[(Long, Long)] = List((1,4), (1,9), (1,16), (1,25), (4,9), (4,16), (4,25), (9,16), (9,25), (16,25))
Improved this using BigInt square-root algorithm as below:
def genTups(N1:BigInt,N2:BigInt) ={
def sqt(n:BigInt):BigInt = {
var a = BigInt(1)
var b = (n>>5)+BigInt(8)
while((b-a) >= 0) {
var mid:BigInt = (a+b)>>1
if(mid*mid-n> 0) b = mid-1
else a = mid+1
}; a-1 }
val x = for(s<- sqt(N1) to sqt(N2)) yield s*s;
val y = x.combinations(2).map{ case Vector(a,b) => (a,b)}.toList
y.filter(t=> (t._1*30/t._2)>=1)
}
I appreciate any help to improve in my algorithm .
You can avoid sqrt in you algorithm by changing the way you calculate x to this:
val x = (BigInt(1) to N).map(x => x*x).takeWhile(_ <= N)
The final function is then:
def genTups(N: BigInt) = {
val x = (BigInt(1) to N).map(x => x*x).takeWhile(_ <= N)
val y = x.combinations(2).map { case Vector(a, b) if (a < b) => (a, b) }.toList
y.filter(t => (t._1 * 30 / t._2) >= 1)
}
You can also re-write this as a single chain of operations like this:
def genTups(N: BigInt) =
(BigInt(1) to N)
.map(x => x * x)
.takeWhile(_ <= N)
.combinations(2)
.map { case Vector(a, b) if a < b => (a, b) }
.filter(t => (t._1 * 30 / t._2) >= 1)
.toList
In a quest for performance, I came up with this recursive version that appears to be significantly faster
def genTups(N1: BigInt, N2: BigInt) = {
def sqt(n: BigInt): BigInt = {
var a = BigInt(1)
var b = (n >> 5) + BigInt(8)
while ((b - a) >= 0) {
var mid: BigInt = (a + b) >> 1
if (mid * mid - n > 0) {
b = mid - 1
} else {
a = mid + 1
}
}
a - 1
}
#tailrec
def loop(a: BigInt, rem: List[BigInt], res: List[(BigInt, BigInt)]): List[(BigInt, BigInt)] =
rem match {
case Nil => res
case head :: tail =>
val a30 = a * 30
val thisRes = rem.takeWhile(_ <= a30).map(b => (a, b))
loop(head, tail, thisRes.reverse ::: res)
}
val squares = (sqt(N1) to sqt(N2)).map(s => s * s).toList
loop(squares.head, squares.tail, Nil).reverse
}
Each recursion of the loop adds all the matching pairs for a given value of a. The result is built in reverse because adding to the front of a long list is much faster than adding to the tail.
Firstly create a function to check if number if perfect square or not.
def squareRootOfPerfectSquare(a: Int): Option[Int] = {
val sqrt = math.sqrt(a)
if (sqrt % 1 == 0)
Some(sqrt.toInt)
else
None
}
Then, create another func that will calculate this list of tuples according to the conditions mentioned above.
def generateTuples(n1:Int,n2:Int)={
for{
b <- 1 to n2;
a <- 1 to n1 if(b>a && squareRootOfPerfectSquare(b).isDefined && squareRootOfPerfectSquare(a).isDefined)
} yield ( (a,b) )
}
Then on calling the function with parameters generateTuples(5,10)
you will get an output as
res0: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,4), (1,9), (4,9))
Hope that helps !!!

Scala - Remove while loop in quick sort

def QuickSort(arr:Array[Int],first:Int,last:Int): List[Int] = {
var pivot:Int = 0
var temp:Int = 0
if (first < last) {
pivot = first
var i:Int = first
var j:Int = last;
while(i<j){
while(arr(i) <= arr(pivot) && i < last)
i=i+1
while(arr(j) > arr(pivot))
j=j+1
if(i<j)
{
temp = arr(i)
arr(i) = arr(j)
arr(j) = temp
}
}
temp = arr(pivot)
arr(pivot) = arr(j)
arr(j) = temp
QuickSort(arr, first, j-1)
QuickSort(arr, j+1, last)
}
arr.toList
}
Hello I m new to scala and trying to implement quick sort. Program is working correctly but I want to remove the while loop since I read that while and do while are not recommended in scala because they do not return any value.
Is there any way to remove while loop in above code.
The classic quicksort algorithm, as you've coded here, requires a mutable collection (like Array) and the swapping of element values, which requires mutable variables (i.e. var). These things are discouraged in functional programming and aren't held in high esteem in the Scala community.
Here's a similar approach that is a little more in keeping to the spirit of the FP ethic.
// pseudo-quicksort -- from Array[Int] to List[Int]
def pqs(arr:Array[Int]): List[Int] = arr match {
case Array() => List()
case Array(x) => List(x)
case Array(x,y) => if (x < y) List(x,y) else List(y,x)
case _ => val (below, above) = arr.partition(_ < arr(0))
pqs(below) ++ List(arr(0)) ++ pqs(above.tail)
}
Better yet is to use one of the sort methods (sortBy, sortWith, sorted) as offered in the standard library.
Not so elegant, but without while:
def QuickSort(l: List[Int]) : List[Int] = {
if( l.length == 0) return Nil
if( l.length == 1 ) return arr
val pivot = arr(arr.length / 2)
val lesserThanPivot = l.filter( _ < pivot)
val equalToPivot = l.filter( _ == pivot)
val biggerThanPivot = l.filter( _ > pivot)
QuickSort( lesserThanPivot ) ++ equalToPivot.tail ++ List(pivot) ++ QuickSort(biggerThanPivot)
}

Kendall tau distance in Scala

Is this a correct implementation of Kendall tau distance in Scala
def distance[A : Ordering](s: Seq[A], t: Seq[A]): Int = {
assert(s.size == t.size, "Both sequences should be of the same length")
s.combinations(2).zip(t.combinations(2)).count {
case (Seq(s1, s2), Seq(t1, t2)) =>
(s1 > s2 && t1 < t2) || (s1 < s2 && t1 > t2)
}
}
The problem is I do not have enough data to test the algorithm on, only a few examples from Wikipedia. And I do not understand the algorithm well enough to generate my own test data. Most sources are about Kendall tau rank correlation coefficient, which is related but different animal. Maybe I could somehow derive one from the other?
For now let's say that performance is not important.
UPDATE
So, now I have three implementations of Kendall tau distance algorithm. Two of them (distance1 and distance3) give identical results (see bellow). So, which one is correct?
import scala.math.Ordering.Implicits._
val permutations = Random.shuffle((0 until 5).permutations).take(100)
println("s\tt\tDist1\tDist2\tDist3")
permutations.sliding(2).foreach { case Seq(s, t) =>
println(s.mkString(",")+"\t"+t.mkString(",")+"\t"+distance1(s, t)+"\t"+distance2(s, t)+
"\t"+distance3(s, t))
}
def distance1[A : Ordering](s: Seq[A], t: Seq[A]): Int = {
assert(s.size == t.size, "Both sequences should be of the same length")
s.combinations(2).zip(t.combinations(2)).count { case (Seq(s1, s2), Seq(t1, t2)) =>
(s1 > s2 && t1 < t2) || (s1 < s2 && t1 > t2)
}
}
def distance2[A](a: Seq[A], b: Seq[A]): Int = {
val aMap = a.zipWithIndex.toMap // map of a items to their ranks
val bMap = b.zipWithIndex.toMap // map of b items to their ranks
a.combinations(2).count{case Seq(i, j) =>
val a1 = aMap.get(i).get // rank of i in A
val a2 = aMap.get(j).get // rank of j in A
val b1 = bMap.get(i).get // rank of i in B
val b2 = bMap.get(j).get // rank of j in B
a1.compare(a2) != b1.compare(b2)
}
}
def distance3(τ_1: Seq[Int], τ_2: Seq[Int]) =
(0 until τ_1.size).map { i =>
(i+1 until τ_2.size).count { j =>
(τ_1(i) < τ_1(j) && τ_2(i) > τ_2(j)) || (τ_1(i) > τ_1(j) && τ_2(i) < τ_2(j))
}
}.sum
And here are some results:
s t Dist1 Dist2 Dist3
3,0,4,2,1 1,4,3,0,2 6 6 6
1,4,3,0,2 0,4,1,2,3 3 5 3
0,4,1,2,3 4,0,1,3,2 8 2 8
4,0,1,3,2 1,2,0,4,3 4 6 4
1,2,0,4,3 2,3,1,4,0 3 5 3
2,3,1,4,0 1,0,3,2,4 8 6 8
1,0,3,2,4 1,3,2,4,0 7 3 7
1,3,2,4,0 4,3,0,1,2 6 6 6
4,3,0,1,2 1,0,2,4,3 7 7 7
1,0,2,4,3 3,4,1,2,0 8 8 8
3,4,1,2,0 1,4,2,0,3 5 5 5
1,4,2,0,3 1,0,3,4,2 8 4 8
I don't think this is quite right. Here's some quickly written code that emphasizes that what you are comparing is the rank of the items in the sequences (you don't really want to keep those get(n).get calls in your code though). I used compare, too, which I think makes sense:
def tauDistance[A](a: Seq[A], b: Seq[A]) = {
val aMap = a.zipWithIndex.toMap // map of a items to their ranks
val bMap = b.zipWithIndex.toMap // map of b items to their ranks
a.combinations(2).count{case Seq(i, j) =>
val a1 = aMap.get(i).get // rank of i in A
val a2 = aMap.get(j).get // rank of j in A
val b1 = bMap.get(i).get // rank of i in B
val b2 = bMap.get(j).get // rank of j in B
a1.compare(a2) != b1.compare(b2)
}
}
So, the Wikipedia defines K on the ranks of the elements like this:
K(τ_1,τ_2) = |{(i,j): i < j, (τ_1(i) < τ_1(j) && τ_2(i) > τ_2(j)) || (τ_1(i) > τ_1(j) && τ_2(i) < τ_2(j))}|
We can implement this pretty directly in Scala, remembering that the inputs are sequences of ranks, not the items themselves:
def K(τ_1: Seq[Int], τ_2: Seq[Int]) =
(0 until τ_1.size).map{i =>
(i+1 until τ_2.size).count{j =>
(τ_1(i) < τ_1(j) && τ_2(i) > τ_2(j)) || (τ_1(i) > τ_1(j) && τ_2(i) < τ_2(j))
}
}.sum
This is actually a bit preferable to the tauDistance function above, since that function assumes all the items are unique (and so will fail if the sequences have duplicates) while this one works on the ranks directly.
Working with combinatoric functions is hard sometimes, and it's often not enough just to have unit tests that pass.

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)

Scala - can 'for-yield' clause yields nothing for some condition?

In Scala language, I want to write a function that yields odd numbers within a given range. The function prints some log when iterating even numbers. The first version of the function is:
def getOdds(N: Int): Traversable[Int] = {
val list = new mutable.MutableList[Int]
for (n <- 0 until N) {
if (n % 2 == 1) {
list += n
} else {
println("skip even number " + n)
}
}
return list
}
If I omit printing logs, the implementation become very simple:
def getOddsWithoutPrint(N: Int) =
for (n <- 0 until N if (n % 2 == 1)) yield n
However, I don't want to miss the logging part. How do I rewrite the first version more compactly? It would be great if it can be rewritten similar to this:
def IWantToDoSomethingSimilar(N: Int) =
for (n <- 0 until N) if (n % 2 == 1) yield n else println("skip even number " + n)
def IWantToDoSomethingSimilar(N: Int) =
for {
n <- 0 until N
if n % 2 != 0 || { println("skip even number " + n); false }
} yield n
Using filter instead of a for expression would be slightly simpler though.
I you want to keep the sequentiality of your traitement (processing odds and evens in order, not separately), you can use something like that (edited) :
def IWantToDoSomethingSimilar(N: Int) =
(for (n <- (0 until N)) yield {
if (n % 2 == 1) {
Option(n)
} else {
println("skip even number " + n)
None
}
// Flatten transforms the Seq[Option[Int]] into Seq[Int]
}).flatten
EDIT, following the same concept, a shorter solution :
def IWantToDoSomethingSimilar(N: Int) =
(0 until N) map {
case n if n % 2 == 0 => println("skip even number "+ n)
case n => n
} collect {case i:Int => i}
If you will to dig into a functional approach, something like the following is a good point to start.
First some common definitions:
// use scalaz 7
import scalaz._, Scalaz._
// transforms a function returning either E or B into a
// function returning an optional B and optionally writing a log of type E
def logged[A, E, B, F[_]](f: A => E \/ B)(
implicit FM: Monoid[F[E]], FP: Pointed[F]): (A => Writer[F[E], Option[B]]) =
(a: A) => f(a).fold(
e => Writer(FP.point(e), None),
b => Writer(FM.zero, Some(b)))
// helper for fixing the log storage format to List
def listLogged[A, E, B](f: A => E \/ B) = logged[A, E, B, List](f)
// shorthand for a String logger with List storage
type W[+A] = Writer[List[String], A]
Now all you have to do is write your filtering function:
def keepOdd(n: Int): String \/ Int =
if (n % 2 == 1) \/.right(n) else \/.left(n + " was even")
You can try it instantly:
scala> List(5, 6) map(keepOdd)
res0: List[scalaz.\/[String,Int]] = List(\/-(5), -\/(6 was even))
Then you can use the traverse function to apply your function to a list of inputs, and collect both the logs written and the results:
scala> val x = List(5, 6).traverse[W, Option[Int]](listLogged(keepOdd))
x: W[List[Option[Int]]] = scalaz.WriterTFunctions$$anon$26#503d0400
// unwrap the results
scala> x.run
res11: (List[String], List[Option[Int]]) = (List(6 was even),List(Some(5), None))
// we may even drop the None-s from the output
scala> val (logs, results) = x.map(_.flatten).run
logs: List[String] = List(6 was even)
results: List[Int] = List(5)
I don't think this can be done easily with a for comprehension. But you could use partition.
def getOffs(N:Int) = {
val (evens, odds) = 0 until N partition { x => x % 2 == 0 }
evens foreach { x => println("skipping " + x) }
odds
}
EDIT: To avoid printing the log messages after the partitioning is done, you can change the first line of the method like this:
val (evens, odds) = (0 until N).view.partition { x => x % 2 == 0 }