Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FP sorting function in scala explained

I've started to learn FP with Scala with the book "Functional Programming in Scala" (Chiusano & Bjarnason, Manning Publications, 2014)

There's a exercise in which you have to implement a function which checks whether an Array is sorted according to a given comparison function (solution as provided by the authors):

def isSorted[A](as: Array[A], ordering: (A, A) => Boolean): Boolean = {
@annotation.tailrec
 def go(n: Int): Boolean =
   if (n >= as.length - 1) true
   else if (ordering(as(n), as(n + 1))) false
   else go(n + 1)

 go(0)
}

When invoking this function e. g. like this:

isSorted(Array(1, 3, 5, 7), (x: Int, y: Int) => x > y) //evaluates to TRUE

I would expect it to be evaluated to false (not true) because the arr is not being sorted in descending order (7,5,3,1)

 //Array sorted in descending order ">" as sorting-operator
scala> List(10, 5, 8, 1, 7).sortWith(_ > _)
res2: List[Int] = List(10, 8, 7, 5, 1)

May anyone can explain the function as I just don't get it. A thoroughly explanation is much appreciated.

Thank you very much.

like image 815
brandshaide Avatar asked Apr 28 '26 05:04

brandshaide


1 Answers

The problem is here:

else if (ordering(as(n), as(n + 1))) false

Given the predicate x > y, this will yield false for every value in the array, thus passing continuing to the else clause until n >= as.length - 1 is reached, which will make the method (falsely) yield true.

We can negate the predicate inside isSorted:

def isSorted[A](as: Array[A], ordering: (A, A) => Boolean): Boolean = {
@annotation.tailrec
 def go(n: Int): Boolean =
   if (n >= as.length - 1) true
   else if (!ordering(as(n), as(n + 1))) false
   else go(n + 1)

 go(0)
}

And then:

scala> isSorted(Array(1, 3, 5, 7), (x: Int, y: Int) => x > y)
res4: Boolean = false
like image 65
Yuval Itzchakov Avatar answered Apr 29 '26 19:04

Yuval Itzchakov