It doesn't seem like you need an ordered T for your split function, since it just calls the predicate function.
It does not work (presumably), but simply compiles. Other questions for checking the code would be extra brackets and the like.
package evident object Test extends App { def partition[T](pred: (T)=>Boolean, list:List[T]): Pair[List[T],List[T]] = { list.foldLeft(Pair(List[T](),List[T]()))((pair,x) => if(pred(x))(pair._1, x::pair._2) else (x::pair._1, pair._2)) } def bestN[U,V<%Ordered[V]](list:List[(U,V)], n:Int): List[(U,V)] = { list match { case pivot::other => { println(s"pivot: $pivot and rest ${other mkString ","}") def cmp(a: (U,V), b: (U,V)) = (a: OrderedPair[U,V]) < (b: OrderedPair[U,V]) val (smaller,bigger) = partition(((x:(U,V)) => cmp(x, pivot)), list) //val (smaller,bigger) = list partition ((x:(U,V)) => cmp(x, pivot)) println(s"smaller: ${smaller mkString ","} and bigger ${bigger mkString ","}") val s = smaller.size if (s == n) smaller else if (s+1 == n) pivot::smaller else if (s < n) bestN(bigger, ns-1) else bestN(smaller, n) } case Nil => Nil } } implicit class OrderedPair[T, V <% Ordered[V]](tv: (T,V)) extends Pair(tv._1, tv._2) with Ordered[OrderedPair[T,V]] { override def compare(that:OrderedPair[T,V]) : Int = this._2.compare(that._2) } val z = List(Pair("alfred",1),Pair("peter",4),Pair("Xaver",1),Pair("Ulf",2),Pair("Alfons",6),Pair("Gulliver",3)) println(bestN(z, 3)) }
I found that the section function is hard to read; you need a function to separate all the guys. Here are some formulations that also use the agreement, the results accepted by the filter go to the left, deviations go to the right.
def partition[T](p: T => Boolean, list: List[T]) = ((List.empty[T], List.empty[T]) /: list) { (s, t) => if (p(t)) (t :: s._1, s._2) else (s._1, t :: s._2) } def partition2[T](p: T => Boolean, list: List[T]) = ((List.empty[T], List.empty[T]) /: list) { case ((is, not), t) if p(t) => (t :: is, not) case ((is, not), t) => (is, t :: not) } // like List.partition def partition3[T](p: T => Boolean, list: List[T]) = { import collection.mutable.ListBuffer val is, not = new ListBuffer[T] for (t <- list) (if (p(t)) is else not) += t (is.toList, not.toList) }
This may be closer to the source code:
def bestN[U, V <% Ordered[V]](list: List[(U,V)], n: Int): List[(U,V)] = { require(n >= 0) require(n <= list.length) if (n == 0) Nil else if (n == list.length) list else list match { case pivot :: other => println(s"pivot: $pivot and rest ${other mkString ","}") def cmp(x: (U,V)) = x._2 < pivot._2 val (smaller, bigger) = partition(cmp, other) // other partition cmp println(s"smaller: ${smaller mkString ","} and bigger ${bigger mkString ","}") val s = smaller.size if (s == n) smaller else if (s == 0) pivot :: bestN(bigger, n - 1) else if (s < n) smaller ::: bestN(pivot :: bigger, n - s) else bestN(smaller, n) case Nil => Nil } }
The arrow values ββare more common:
val z = List( "alfred" -> 1, "peter" -> 4, "Xaver" -> 1, "Ulf" -> 2, "Alfons" -> 6, "Gulliver" -> 3 )