Created
August 4, 2010 00:10
-
-
Save etorreborre/507424 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This fails to compile with: | |
type mismatch; | |
found : Iterable[T] | |
required: CC[T] | |
else if (predicate(xs.head)) xs.drop(1) | |
^ | |
type mismatch; | |
found : Iterable[T] | |
required: CC[T] | |
else xs.take(1) ++ xs.tail.removeFirst(predicate) | |
*/ | |
object o { | |
implicit def extendedIterable[T, CC[T] <: Iterable[T]](xs: CC[T]) = new ExtendedIterable(xs) | |
class ExtendedIterable[T, CC[T] <: Iterable[T]](xs: CC[T]) { | |
def removeFirst(predicate: T => Boolean): CC[T] = { | |
if (xs.isEmpty) xs | |
else if (predicate(xs.head)) xs.drop(1) | |
else xs.take(1) ++ xs.tail.removeFirst(predicate) | |
} | |
} | |
val l: List[Int] = List(1, 2).removeFirst((i: Int) => i > 0) | |
println(l) | |
} |
import collection.generic.CanBuildFrom
import collection.IterableLike
import collection.immutable.BitSet
import collection.immutable.Queue
trait IterableRemovals0 {
// Must be in base class since it clashes with extendedIterable1 for types such as List or Set
// This makes extendedIterable1 take priority, but we get this one for types such as BitSet
implicit def extendedIterable0[CC <: IterableLike[Int, CC]](xs: CC) = new ExtendedIterable0[CC](xs)
class ExtendedIterable0[CC <: IterableLike[Int, CC]](xs: CC) {
def removeFirst(predicate: Int => Boolean)(implicit cbf: CanBuildFrom[CC, Int, CC]): CC = {
if (xs.isEmpty) xs
else if (predicate(xs.head)) xs.drop(1)
else xs.take(1) ++ xs.tail.removeFirst(predicate)
}
}
// This one doesn't compile for some reason
//
// implicit def extendedIterable0[T, CC <: IterableLike[T, CC]](xs: CC) = new ExtendedIterable0[T, CC](xs)
// class ExtendedIterable0[T, CC <: IterableLike[T, CC]](xs: CC) {
// def removeFirst(predicate: T => Boolean)(implicit cbf: CanBuildFrom[CC, T, CC]): CC = {
// if (xs.isEmpty) xs
// else if (predicate(xs.head)) xs.drop(1)
// else xs.take(1) ++ xs.tail.removeFirst(predicate)
// }
// }
}
trait IterableRemovals extends IterableRemovals0 {
implicit def extendedIterable1[T, CC[T] <: IterableLike[T, CC[T]]](xs: CC[T]) = new ExtendedIterable1[T, CC](xs)
class ExtendedIterable1[T, CC[T] <: IterableLike[T, CC[T]]](xs: CC[T]) {
def removeFirst(predicate: T => Boolean)(implicit cbf: CanBuildFrom[CC[T], T, CC[T]]): CC[T] = {
if (xs.isEmpty) xs
else if (predicate(xs.head)) xs.drop(1)
else xs.take(1) ++ xs.tail.removeFirst(predicate)
}
}
implicit def extendedIterable2[T, U, CC[T,U] <: IterableLike[(T,U), CC[T,U]]](xs: CC[T,U]) = new ExtendedIterable2[T, U, CC](xs)
class ExtendedIterable2[T, U, CC[T,U] <: IterableLike[(T,U), CC[T,U]]](xs: CC[T,U]) {
def removeFirst(predicate: ((T,U)) => Boolean)(implicit cbf: CanBuildFrom[CC[T,U], (T,U), CC[T,U]]): CC[T,U] = {
if (xs.isEmpty) xs
else if (predicate(xs.head)) xs.drop(1)
else xs.take(1) ++ xs.tail.removeFirst(predicate)
}
}
}
object Eric extends Application with IterableRemovals {
val l: List[Int] = List(1, 2).removeFirst((i: Int) => i > 0)
println(l)
val l2: List[String] = List("1", "2").removeFirst((s: String) => s.toInt > 0)
println(l2)
val s: Set[Int] = Set(1, 2).removeFirst((i: Int) => i > 0)
println(s)
val s2: Set[String] = Set("1", "2").removeFirst((s: String) => s.toInt > 0)
println(s2)
val b: BitSet = BitSet(1, 2).removeFirst((i: Int) => i > 0)
println(b)
val q: Queue[Int] = Queue(1, 2).removeFirst((i: Int) => i > 0)
println(q)
val q2: Queue[String] = Queue("1", "2").removeFirst((s: String) => s.toInt > 0)
println(q2)
val m: Map[Int,Int] = Map(1 -> 8, 2 -> 9).removeFirst{ case (x,y) => x > 0 }
println(m)
val m2: Map[String,Int] = Map("1" -> 8, "2" -> 9).removeFirst{ case (x,y) => x.toInt > 0 }
println(m2)
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Erg. Sorry about that copy and paste problem. I'll stop now...