Scala code analyzer targets case variable names that are identical to the outer matched varables - "suspicous shadowing" - scala

In the following code snippet in which the outer match vars (x,y) are case matched by (xx,yy):
scala> val (x,y) = (1,2)
x: Int = 1
y: Int = 2
scala> (x,y) match {
| case (xx:Int, yy:Int) => println(s"x=$x xx=$xx")
| }
x=1 xx=1
We could have also written that code as follows:
scala> (x,y) match {
| case (x:Int, y:Int) => println(s"x=$x y=$y")
| }
x=1 y=2
In this latter case the Scala Code Analyzers will inform us:
Suspicious shadowing by a Variable Pattern
OK. But is there any situation where we could end up actually misusing the inner variable (x or y) in place of the original outer match variables?
It seems this is purely stylistic? No actual possibility for bugs? If so i would be interested to learn what the bugs could be.

This could be confusing:
val x = Some(1)
val y = Some(2)
(x, y) match {
case (Some(x), Some(y)) => println(s"x=$x y=$y")
}
x and y have different types depending on whether you are inside or outside of the match. If this code wasn't using simply Option, and was several lines longer, it could be rather difficult to reason about.
Could any bugs arise from this? None that I can think of that aren't horribly contrived. You could for example, mistake one for another.
val list = List(1,2,3)
list match {
case x :: y :: list => list // List(3) and not List(1,2,3)
case x :: list => list // List with 1 element, should the outer list have size 2
case _ => list // Returns the outer list when empty
}
Not to mention what a horrible mess that is. Within the match, list sometimes refers to an inner symbol, and sometimes the outer list.

It's just code that's unnecessarily complicated to read and understand, there are no special bugs that could happen.

Related

Second Element of a List

From the Book programming in Scala I got the following line of code:
val second: List[ Int] => Int = { case x :: y :: _ => y }
//warning: match may not be exhaustive.
It states that this function will return the second element of a list of integers if the list is not empty or nil. Stil this part is a bit awkward to me:
case x :: y :: _
How does this ecxactly work? Does this mathches any list with at least 2 Elements and than return the second? If so can somebody still explain the syntax? I understood that :: is invoked on the right operand. So it could be written as
(_.::(y)).::(X)
Still I than don't get why this would return 2
val second: List[ Int] => Int = { case x :: y :: _ => y }
var x = List(1,2)
second(x) //returns 2
In the REPL, you can type:
scala> val list = "a" :: "b" :: Nil
list: List[String] = List(a, b)
which is to be read from right to left, and means take the end of a List (Nil), prepend String "b" and to this List ("b" :: Nil) prepend String a, a :: ("b" :: Nil) but you don't need the parens, so it can be written "a" :: "b" :: Nil.
In pattern matching you will more often see:
... list match {
case Nil => // ...
case x :: xs => // ...
}
to distinguish between empty list, and nonempty, where xs might be a rest of list, but matches Nil too, if the whole list is ("b" :: Nil) for example, then x="b" and xs=Nil.
But if list= "a" :: "b" :: Nil, then x="a" and xs=(b :: Nil).
In your example, the deconstruction is just one more step, and instead of a name like xs, the joker sign _ is used, indicating, that the name is probably not used and doesn't play a role.
The value second is of function type, it takes List[Int] and returns Int.
If the list has first element ("x"), and a second element ("y"), and whatever comes next (we don't care about it), we simply return the element "y" (which is the second element of the list).
In any other case, the function is not defined. You can check that:
scala> val second: PartialFunction[List[Int], Int] = {
| case x :: y :: _ => y
| }
second: PartialFunction[List[Int],Int] = <function1>
scala> second.isDefinedAt(List(1,2,3))
res18: Boolean = true
scala> second.isDefinedAt(List(1,2))
res19: Boolean = true
scala> second.isDefinedAt(List(0))
res20: Boolean = false
First of all. When you think about pattern matching you should think about matching a structure.
The first part of the case statement describes a structure. This structure may describe one or more things (variables) which are useful to deriving your result.
In your example, you are interested in deriving the second element of a list. A shorthand to build a list in Scala is to use :: method (also called cons). :: can also be used to describe a structure in case statement. At this time, you shouldn't think about evaluation of the :: method in first part of case. May be that's why you are saying about evaluation of _.::(y).::(x). The :: cons operator help us describe the structure of the list in terms of its elements. In this case, the first element (x) , the second element (y) and the rest of it (_ wildcard). We are interested in a structure that is a list with at least 2 elements and the third can be anything - a Nil to indicate end of list or another element - hence the wildcard.
The second part of the case statement, uses the second element to derive the result (y).
More on List and Consing
List in Scala is similar to a LinkedList. You know about the first element called head and start of the rest of the list. When traversing the linked list you stop if the rest of the list is Nil. This :: cons operator helps us visualise the structure of the linked list. Although Scala compile would actually be calling :: methods evaluating from right to left as you described _.::(y).::(x)
As an aside, you might have already noticed that the Scala compiler might be complain that your match isn't exhaustive. This means that this second method would work for list of any size. Because there isn't any case statement to describe list with zero or one element. Also, as mentioned in comments of previous answers, if you aren't interested in first element you can describe it as a wildcard _.
case _ :: y :: _ => y
I hope this helped.
If you see the structure of list in scala its head::tail, first element is treated as head and all remaining ones as tail(Nil will be the last element of tail). whenever you do x::y::_, x will match the head of the list and remaining will be tail and again y will match the head of the next list(tail of first list)
eg:
val l = List(1,2,3,4,5)
you can see this list in differnt ways:
1::2::3::4::5::Nil
1::List(2,3,4,5)
1::2::List(2,3,4,5)
and so on
So try matching the pattern. In your question y will give the second element

What's the reasoning behind adding the "case" keyword to Scala?

Apart from:
case class A
... case which is quite useful?
Why do we need to use case in match? Wouldn't:
x match {
y if y > 0 => y * 2
_ => -1
}
... be much prettier and concise?
Or why do we need to use case when a function takes a tuple? Say, we have:
val z = List((1, -1), (2, -2), (3, -3)).zipWithIndex
Now, isn't:
z map { case ((a, b), i) => a + b + i }
... way uglier than just:
z map (((a, b), i) => a + b + i)
...?
First, as we know, it is possible to put several statements for the same case scenario without needing some separation notation, just a line jump, like :
x match {
case y if y > 0 => y * 2
println("test")
println("test2") // these 3 statements belong to the same "case"
}
If case was not needed, compiler would have to find a way to know when a line is concerned by the next case scenario.
For example:
x match {
y if y > 0 => y * 2
_ => -1
}
How compiler would know whether _ => -1 belongs to the first case scenario or represents the next case?
Moreover, how compiler would know that the => sign doesn't represent a literal function but the actual code for the current case?
Compiler would certainly need a kind of code like this allowing cases isolation:
(using curly braces, or anything else)
x match {
{y if y > 0 => y * 2}
{_ => -1} // confusing with literal function notation
}
And surely, solution (provided currently by scala) using case keyword is a lot more readable and understandable than putting some way of separation like curly braces in my example.
Adding to #Mik378's answer:
When you write this: (a, b) => something, you are defining an anonymous Function2 - a function that takes two parameters.
When you write this: case (a, b) => something, you are defining an anonymous PartialFunction that takes one parameter and matches it against a pair.
So you need the case keyword to differentiate between these two.
The second issue, anonymous functions that avoid the case, is a matter of debate:
https://groups.google.com/d/msg/scala-debate/Q0CTZNOekWk/z1eg3dTkCXoJ
Also: http://www.scala-lang.org/old/node/1260
For the first issue, the choice is whether you allow a block or an expression on the RHS of the arrow.
In practice, I find that shorter case bodies are usually preferable, so I can certainly imagine your alternative syntax resulting in crisper code.
Consider one-line methods. You write:
def f(x: Int) = 2 * x
then you need to add a statement. I don't know if the IDE is able to auto-add parens.
def f(x: Int) = { val res = 2*x ; res }
That seems no worse than requiring the same syntax for case bodies.
To review, a case clause is case Pattern Guard => body.
Currently, body is a block, or a sequence of statements and a result expression.
If body were an expression, you'd need braces for multiple statements, like a function.
I don't think => results in ambiguities since function literals don't qualify as patterns, unlike literals like 1 or "foo".
One snag might be: { case foo => ??? } is a "pattern matching anonymous function" (SLS 8.5). Obviously, if the case is optional or eliminated, then { foo => ??? } is ambiguous. You'd have to distinguish case clauses for anon funs (where case is required) and case clauses in a match.
One counter-argument for the current syntax is that, in an intuition deriving from C, you always secretly hope that your match will compile to a switch table. In that metaphor, the cases are labels to jump to, and a label is just the address of a sequence of statements.
The alternative syntax might encourage a more inlined approach:
x match {
C => c(x)
D => d(x)
_ => ???
}
#inline def c(x: X) = ???
//etc
In this form, it looks more like a dispatch table, and the match body recalls the Map syntax, Map(a -> 1, b -> 2), that is, a tidy simplification of the association.
One of the key aspects of code readability is the words that grab your attention. For example,
return grabs your attention when you see it because you know that it is such a decisive action (breaking out of the function and possible sending a value back to the caller).
Another example is break--not that I like break, but it gets your attention.
I would agree with #Mik378 that case in Scala is more readable than the alternatives. Besides the compiler confusion he mentions, it gets your attention.
I am all for concise code, but there is a line between concise and illegible. I will gladly make the trade of 4n characters (where n is the number of cases) for the substantial readability that I get in return.

Explain some scala code - beginner

I've encountered this scala code and I'm trying to work out what its doing except the fact it returns an int. I'm unsure of these three lines :
l match {
case h :: t =>
case _ => 0
Function :
def iterate(l: List[Int]): Int =
l match {
case h :: t =>
if (h > n) 0
case _ => 0
}
First, you define a function called iterate and you specified the return type as Int. It has arity 1, parameter l of type List[Int].
The List type is prominent throughout functional programming, and it's main characteristics being that it has efficient prepend and that it is easy to decompose any List into a head and tail. The head would be the first element of the list (if non-empty) and the tail would be the rest of the List(which itself is a List) - this becomes useful for recursive functions that operate on List.
The match is called pattern matching.. it's essentially a switch statement in the C-ish languages, but much more powerful - the switch restricts you to constants (at least in C it does), but there is no such restriction with match.
Now, your first case you have h :: t - the :: is called a "cons", another term from functional programming. When you create a new List from another List via a prepend, you can use the :: operator to do it.
Example:
val oldList = List(1, 2, 3)
val newList = 0 :: oldList // newList == List(0, 1, 2, 3)
In Scala, operators that end with a : are really a method of the right hand side, so 0 :: oldList is the equivalent of oldList.::(0) - the 0 :: oldList is syntactic sugar that makes it easier to read.
We could've defined oldList like
val oldList = 1 :: 2 :: 3 :: Nil
where Nil represents an empty List. Breaking this down into steps:
3 :: Nil is evaluated first, creating the equivalent of a List(3) which has head 3 and empty tail.
2 is prepended to the above list, creative a new list with head 2 and tail List(3).
1 is prepended, creating a new list with head 1 and tail List(2, 3).
The resulting List of List(1, 2, 3) is assigned to the val oldList.
Now when you use :: to pattern match you essentially decompose a List into a head and tail, like the reverse of how we created the List above. Here when you do
l match {
case h :: t => ...
}
you are saying decompose l into a head and tail if possible. If you decompose successfully, you can then use these h and t variables to do whatever you want.. typically you would do something like act on h and call the recursive function on t.
One thing to note here is that your code will not compile.. you do an if (h > n) 0 but there is no explicit else so what happens is your code looks like this to the compiler:
if (h > n) 0
else { }
which has type AnyVal (the common supertype of 0 and "nothing"), a violation of your Int guarentee - you're going to have to add an else branch with some failure value or something.
The second case _ => is like a default in the switch, it catches anything that failed the head/tail decomposition in your first case.
Your code essentially does this:
Take the l List parameter and see if it can be decomposed into a head and tail.
If it can be, compare the head against (what I assume to be) a variable in the outer scope called n. If it is greater than n, the function returns 0. (You need to add what happens if it's not greater)
If it cannot be decomposed, the function returns 0.
This is called pattern matching. It's like a switch statement, but more powerful.
Some useful resources:
http://www.scala-lang.org/node/120
http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-4

Matching with custom combinations/operators

I know that you can do matching on lists in a way like
val list = List(1,2,3)
list match {
case head::tail => head
case _ => //whatever
}
so I started to wonder how this works. If I understand correctly, :: is just an operator, so what's to stop me from doing something like
4 match {
case x + 2 => x //I would expect x=2 here
}
If there is a way to create this kind of functionality, how is it done; if not, then why?
Pattern matching takes the input and decomposes it with an unapply function. So in your case, unapply(4) would have to return the two numbers that sum to 4. However, there are many pairs that sum to 4, so the function wouldn't know what to do.
What you need is for the 2 to be accessible to the unapply function somehow. A special case class that stores the 2 would work for this:
case class Sum(addto: Int) {
def unapply(i: Int) = Some(i - addto)
}
val Sum2 = Sum(2)
val Sum2(x) = 5 // x = 3
(It would be nice to be able to do something like val Sum(2)(y) = 5 for compactness, but Scala doesn't allow parameterized extractors; see here.)
[EDIT: This is a little silly, but you could actually do the following too:
val `2 +` = Sum(2)
val `2 +`(y) = 5 // y = 3
]
EDIT: The reason the head::tail thing works is that there is exactly one way to split the head from the tail of a list.
There's nothing inherently special about :: versus +: you could use + if you had a predetermined idea of how you wanted it to break a number. For example, if you wanted + to mean "split in half", then you could do something like:
object + {
def unapply(i: Int) = Some(i-i/2, i/2)
}
and use it like:
scala> val a + b = 4
a: Int = 2
b: Int = 2
scala> val c + d = 5
c: Int = 3
d: Int = 2
EDIT: Finally, this explains that, when pattern matching, A op B means the same thing as op(A,B), which makes the syntax look nice.
Matching with case head :: tail uses an infix operation pattern of the form p1 op p2 which gets translated to op(p1, p2) before doing the actual matching. (See API for ::)
The problem with + is the following:
While it is easy to add an
object + {
def unapply(value: Int): Option[(Int, Int)] = // ...
}
object which would do the matching, you may only supply one result per value. E.g.
object + {
def unapply(value: Int): Option[(Int, Int)] = value match {
case 0 => Some(0, 0)
case 4 => Some(3, 1)
case _ => None
}
Now this works:
0 match { case x + 0 => x } // returns 0
also this
4 match { case x + 1 => x } // returns 3
But this won’t and you cannot change it:
4 match { case x + 2 => x } // does not match
No problem for ::, though, because it is always defined what is head and what is tail of a list.
There are two ::s (pronounced "cons") in Scala. One is the operator on Lists and the other is a class, which represents a non empty list characterized by a head and a tail. So head :: tail is a constructor pattern, which has nothing to do with the operator.

Selection sort in functional Scala

I'm making my way through "Programming in Scala" and wrote a quick implementation of the selection sort algorithm. However, since I'm still a bit green in functional programming, I'm having trouble translating to a more Scala-ish style. For the Scala programmers out there, how can I do this using Lists and vals rather than falling back into my imperative ways?
http://gist.github.com/225870
As starblue already said, you need a function that calculates the minimum of a list and returns the list with that element removed. Here is my tail recursive implementation of something similar (as I believe foldl is tail recursive in the standard library), and I tried to make it as functional as possible :). It returns a list that contains all the elements of the original list (but kindof reversed - see the explanation below) with the minimum as a head.
def minimum(xs: List[Int]): List[Int] =
(List(xs.head) /: xs.tail) {
(ys, x) =>
if(x < ys.head) (x :: ys)
else (ys.head :: x :: ys.tail)
}
This basically does a fold, starting with a list containing of the first element of xs If the first element of xs is smaller than the head of that list, we pre-append it to the list ys. Otherwise, we add it to the list ys as the second element. And so on recursively, we've folded our list into a new list containing the minimum element as a head and a list containing all the elements of xs (not necessarily in the same order) with the minimum removed, as a tail. Note that this function does not remove duplicates.
After creating this helper function, it's now easy to implement selection sort.
def selectionSort(xs: List[Int]): List[Int] =
if(xs.isEmpty) List()
else {
val ys = minimum(xs)
if(ys.tail.isEmpty)
ys
else
ys.head :: selectionSort(ys.tail)
}
Unfortunately this implementation is not tail recursive, so it will blow up the stack for large lists. Anyway, you shouldn't use a O(n^2) sort for large lists, but still... it would be nice if the implementation was tail recursive. I'll try to think of something... I think it will look like the implementation of a fold.
Tail Recursive!
To make it tail recursive, I use quite a common pattern in functional programming - an accumulator. It works a bit backward, as now I need a function called maximum, which basically does the same as minimum, but with the maximum element - its implementation is exact as minimum, but using > instead of <.
def selectionSort(xs: List[Int]) = {
def selectionSortHelper(xs: List[Int], accumulator: List[Int]): List[Int] =
if(xs.isEmpty) accumulator
else {
val ys = maximum(xs)
selectionSortHelper(ys.tail, ys.head :: accumulator)
}
selectionSortHelper(xs, Nil)
}
EDIT: Changed the answer to have the helper function as a subfunction of the selection sort function.
It basically accumulates the maxima to a list, which it eventually returns as the base case. You can also see that it is tail recursive by replacing accumulator by throw new NullPointerException - and then inspect the stack trace.
Here's a step by step sorting using an accumulator. The left hand side shows the list xs while the right hand side shows the accumulator. The maximum is indicated at each step by a star.
64* 25 12 22 11 ------- Nil
11 22 12 25* ------- 64
22* 12 11 ------- 25 64
11 12* ------- 22 25 64
11* ------- 12 22 25 64
Nil ------- 11 12 22 25 64
The following shows a step by step folding to calculate the maximum:
maximum(25 12 64 22 11)
25 :: Nil /: 12 64 22 11 -- 25 > 12, so it stays as head
25 :: 12 /: 64 22 11 -- same as above
64 :: 25 12 /: 22 11 -- 25 < 64, so the new head is 64
64 :: 22 25 12 /: 11 -- and stays so
64 :: 11 22 25 12 /: Nil -- until the end
64 11 22 25 12
You should have problems doing selection sort in functional style, as it is an in-place sort algorithm. In-place, by definition, isn't functional.
The main problem you'll face is that you can't swap elements. Here's why this is important. Suppose I have a list (a0 ... ax ... an), where ax is the minimum value. You need to get ax away, and then compose a list (a0 ... ax-1 ax+1 an). The problem is that you'll necessarily have to copy the elements a0 to ax-1, if you wish to remain purely functional. Other functional data structures, particularly trees, can have better performance than this, but the basic problem remains.
here is another implementation of selection sort (generic version).
def less[T <: Comparable[T]](i: T, j: T) = i.compareTo(j) < 0
def swap[T](xs: Array[T], i: Int, j: Int) { val tmp = xs(i); xs(i) = xs(j); xs(j) = tmp }
def selectiveSort[T <: Comparable[T]](xs: Array[T]) {
val n = xs.size
for (i <- 0 until n) {
val min = List.range(i + 1, n).foldLeft(i)((a, b) => if (less(xs(a), xs(b))) a else b)
swap(xs, i, min)
}
}
You need a helper function which does the selection. It should return the minimal element and the rest of the list with the element removed.
I think it's reasonably feasible to do a selection sort in a functional style, but as Daniel indicated, it has a good chance of performing horribly.
I just tried my hand at writing a functional bubble sort, as a slightly simpler and degenerate case of selection sort. Here's what I did, and this hints at what you could do:
define bubble(data)
if data is empty or just one element: return data;
otherwise, if the first element < the second,
return first element :: bubble(rest of data);
otherwise, return second element :: bubble(
first element :: (rest of data starting at 3rd element)).
Once that's finished recursing, the largest element is at the end of the list. Now,
define bubblesort [data]
apply bubble to data as often as there are elements in data.
When that's done, your data is indeed sorted. Yes, it's horrible, but my Clojure implementation of this pseudocode works.
Just concerning yourself with the first element or two and then leaving the rest of the work to a recursed activity is a lisp-y, functional-y way to do this kind of thing. But once you've gotten your mind accustomed to that kind of thinking, there are more sensible approaches to the problem.
I would recommend implementing a merge sort:
Break list into two sub-lists,
either by counting off half the elements into one sublist
and the rest in the other,
or by copying every other element from the original list
into either of the new lists.
Sort each of the two smaller lists (recursion here, obviously).
Assemble a new list by selecting the smaller from the front of either sub-list
until you've exhausted both sub-lists.
The recursion is in the middle of that, and I don't see a clever way of making the algorithm tail recursive. Still, I think it's O(log-2) in time and also doesn't place an exorbitant load on the stack.
Have fun, good luck!
Thanks for the hints above, they were very inspiring. Here's another functional approach to the selection sort algorithm. I tried to base it on the following idea: finding a max / min can be done quite easily by min(A)=if A=Nil ->Int.MaxValue else min(A.head, min(A.tail)). The first min is the min of a list, the second the min of two numbers. This is easy to understand, but unfortunately not tail recursive. Using the accumulator method the min definition can be transformed like this, now in correct Scala:
def min(x: Int,y: Int) = if (x<y) x else y
def min(xs: List[Int], accu: Int): Int = xs match {
case Nil => accu
case x :: ys => min(ys, min(accu, x))
}
(This is tail recursive)
Now a min version is needed which returns a list leaving out the min value. The following function returns a list whose head is the min value, the tail contains the rest of the original list:
def minl(xs: List[Int]): List[Int] = minl(xs, List(Int.MaxValue))
def minl(xs: List[Int],accu:List[Int]): List[Int] = xs match {
// accu always contains min as head
case Nil => accu take accu.length-1
case x :: ys => minl(ys,
if (x<accu.head) x::accu else accu.head :: x :: accu.tail )
}
Using this selection sort can be written tail recursively as:
def ssort(xs: List[Int], accu: List[Int]): List[Int] = minl(xs) match {
case Nil => accu
case min :: rest => ssort(rest, min::accu)
}
(reverses the order). In a test with 10000 list elements this algorithm is only about 4 times slower than the usual imperative algorithm.
Even though, when coding Scala, I'm used to prefer functional programming style (via combinators or recursion) over imperative style (via variables and iterations), THIS TIME, for this specific problem, old school imperative nested loops result in simpler and more performant code.
I don't think falling back to imperative style is a mistake for certain classes of problems, such as sorting algorithms which usually transform the input buffer in place rather than resulting to a new collection.
My solution is:
package bitspoke.algo
import scala.math.Ordered
import scala.collection.mutable.Buffer
abstract class Sorter[T <% Ordered[T]] {
// algorithm provided by subclasses
def sort(buffer : Buffer[T]) : Unit
// check if the buffer is sorted
def sorted(buffer : Buffer[T]) = buffer.isEmpty || buffer.view.zip(buffer.tail).forall { t => t._2 > t._1 }
// swap elements in buffer
def swap(buffer : Buffer[T], i:Int, j:Int) {
val temp = buffer(i)
buffer(i) = buffer(j)
buffer(j) = temp
}
}
class SelectionSorter[T <% Ordered[T]] extends Sorter[T] {
def sort(buffer : Buffer[T]) : Unit = {
for (i <- 0 until buffer.length) {
var min = i
for (j <- i until buffer.length) {
if (buffer(j) < buffer(min))
min = j
}
swap(buffer, i, min)
}
}
}
As you can see, to achieve parametric polymorphism, rather than using java.lang.Comparable, I preferred scala.math.Ordered and Scala View Bounds rather than Upper Bounds. That's certainly works thanks to Scala Implicit Conversions of primitive types to Rich Wrappers.
You can write a client program as follows:
import bitspoke.algo._
import scala.collection.mutable._
val sorter = new SelectionSorter[Int]
val buffer = ArrayBuffer(3, 0, 4, 2, 1)
sorter.sort(buffer)
assert(sorter.sorted(buffer))
A simple functional program for selection-sort in Scala
def selectionSort(list:List[Int]):List[Int] = {
#tailrec
def selectSortHelper(list:List[Int], accumList:List[Int] = List[Int]()): List[Int] = {
list match {
case Nil => accumList
case _ => {
val min = list.min
val requiredList = list.filter(_ != min)
selectSortHelper(requiredList, accumList ::: List.fill(list.length - requiredList.length)(min))
}
}
}
selectSortHelper(list)
}
You may want to try replacing your while loops with recursion, so, you have two places where you can create new recursive functions.
That would begin to get rid of some vars.
This was probably the toughest lesson for me, trying to move more toward FP.
I hesitate to show solutions here, as I think it would be better for you to try first.
But, if possible you should be using tail-recursion, to avoid problems with stack overflows (if you are sorting a very, very large list).
Here is my point of view on this problem: SelectionSort.scala
def selectionsort[A <% Ordered[A]](list: List[A]): List[A] = {
def sort(as: List[A], bs: List[A]): List[A] = as match {
case h :: t => select(h, t, Nil, bs)
case Nil => bs
}
def select(m: A, as: List[A], zs: List[A], bs: List[A]): List[A] =
as match {
case h :: t =>
if (m > h) select(m, t, h :: zs, bs)
else select(h, t, m :: zs, bs)
case Nil => sort(zs, m :: bs)
}
sort(list, Nil)
}
There are two inner functions: sort and select, which represents two loops in original algorithm. The first function sort iterates through the elements and call select for each of them. When the source list is empty it return bs list as result, which is initially Nil. The sort function tries to search for maximum (not minimum, since we build result list in reversive order) element in source list. It suppose that maximum is head by the default and then just replace it with a proper value.
This is 100% functional implementation of Selection Sort in Scala.
Here is my solution
def sort(list: List[Int]): List[Int] = {
#tailrec
def pivotCompare(p: Int, l: List[Int], accList: List[Int] = List.empty): List[Int] = {
l match {
case Nil => p +: accList
case x :: xs if p < x => pivotCompare(p, xs, accList :+ x)
case x :: xs => pivotCompare(x, xs, accList :+ p)
}
}
#tailrec
def loop(list: List[Int], accList: List[Int] = List.empty): List[Int] = {
list match {
case x :: xs =>
pivotCompare(x, xs) match {
case Nil => accList
case h :: tail => loop(tail, accList :+ h)
}
case Nil => accList
}
}
loop(list)
}