Skip to content

Instantly share code, notes, and snippets.

@etorreborre
Created August 4, 2010 00:10
Show Gist options
  • Save etorreborre/507424 to your computer and use it in GitHub Desktop.
Save etorreborre/507424 to your computer and use it in GitHub Desktop.
/*
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)
}
@etorreborre
Copy link
Author

That's something I was thinking of but I fail to see yet how drop(1) get to use the implicit CanBuildFrom. It's nowhere in the definition of drop so I don't see where it's going to. I'm going to check that. Thanks a lot!

@retronym
Copy link

retronym commented Aug 4, 2010

The ++ needs the CBF.

@retronym
Copy link

retronym commented Aug 4, 2010

@inkytonik
Copy link

Nice. I don't think I would have thought of basing it on IterableLike instead of Iterable. This might solve a problem I've been having generalising Kiama's generic traversal combinators.

In the meantime, here's a version that generalises the above to type constructors with 0 or 2 type parameters and adds more tests. There's one wart though: any idea why the more general version of extendedIterable0 doesn't compile?

@inkytonik
Copy link

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)

}

@inkytonik
Copy link

// Woops, Mardown newbie.  Let's try again.


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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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)

}
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).re

@inkytonik
Copy link

Erg. Sorry about that copy and paste problem. I'll stop now...

@inkytonik
Copy link

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