Skip to content
Browse files

Split @milessabin HasRepr into IsTraversableOnce and IsTraversableLik…

…e type class-ish things.
  • Loading branch information...
1 parent cbcca2c commit f40e521b8f20bf8285b2f6871554a2bc637fe328 @jsuereth jsuereth committed Jun 27, 2012
View
9 src/library/scala/collection/GenTraversableLike.scala
@@ -411,12 +411,3 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
def stringPrefix: String
}
-
-object GenTraversableLike {
- /** Manufacture a conversion from collection representation type `Repr` to
- * its corresponding `GenTraversableLike` given an implicitly available
- * instance of `FromRepr[Repr]`.
- * @see [[scala.collection.generic.FromRepr]]
- */
- implicit def fromRepr[Repr](implicit fr : FromRepr[Repr]) = fr.hasElem
-}
View
36 ...y/scala/collection/generic/FromRepr.scala → ...ollection/generic/IsTraversableLike.scala
@@ -18,39 +18,41 @@ package generic
*
* Example usage,
* {{{
- * import scala.collection.generic.{ CanBuildFrom, FromRepr, HasElem }
- *
- * class FilterMapImpl[A, Repr](val r : Repr)(implicit hasElem : HasElem[Repr, A]) {
- * def filterMap[B, That](f : A => Option[B])
- * (implicit cbf : CanBuildFrom[Repr, B, That]) : That = r.flatMap(f(_).toSeq)
+ * class FilterMapImpl[A, Repr](val r: GenTraversableLike[A, Repr]) {
+ * final def filterMap[B, That](f: A => Option[B])(implicit cbf: CanBuildFrom[Repr, B, That]): That =
+ * r.flatMap(f(_).toSeq)
* }
- *
- * implicit def filterMap[Repr : FromRepr](r : Repr) = new FilterMapImpl(r)
+ * implicit def filterMap[Repr, A](r: Repr)(implicit fr: IsTraversableOnce[Repr]): FilterMapImpl[fr.A,Repr] =
+ * new FilterMapImpl(fr.conversion(r))
*
* val l = List(1, 2, 3, 4, 5)
* List(1, 2, 3, 4, 5) filterMap (i => if(i % 2 == 0) Some(i) else None)
* // == List(2, 4)
* }}}
*
* @author Miles Sabin
+ * @author J. Suereth
* @since 2.10
*/
-trait FromRepr[Repr] {
+trait IsTraversableLike[Repr] {
+ /** The type of elements we can traverse over. */
type A
- val hasElem: HasElem[Repr, A]
+ /** A conversion from the representation type `Repr` to a `GenTraversableLike[A,Repr]`. */
+ val conversion: Repr => GenTraversableLike[A, Repr]
}
-object FromRepr {
+object IsTraversableLike {
import language.higherKinds
- implicit val stringFromRepr : FromRepr[String] { type A = Char } = new FromRepr[String] {
- type A = Char
- val hasElem = implicitly[HasElem[String, Char]]
- }
+ implicit val stringRepr: IsTraversableLike[String] { type A = Char } =
+ new IsTraversableLike[String] {
+ type A = Char
+ val conversion = implicitly[String => GenTraversableLike[Char, String]]
+ }
- implicit def genTraversableLikeFromRepr[C[_], A0]
- (implicit hasElem0: HasElem[C[A0], A0]) : FromRepr[C[A0]] { type A = A0 } = new FromRepr[C[A0]] {
+ implicit def genTraversableLikeRepr[C[_], A0](implicit conv: C[A0] => GenTraversableLike[A0,C[A0]]): IsTraversableLike[C[A0]] { type A = A0 } =
+ new IsTraversableLike[C[A0]] {
type A = A0
- val hasElem = hasElem0
+ val conversion = conv
}
}
View
62 src/library/scala/collection/generic/IsTraversableOnce.scala
@@ -0,0 +1,62 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2012, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package generic
+
+/** Type class witnessing that a collection representation type `Repr` has
+ * elements of type `A` and has a conversion to `GenTraversableOnce[A]`.
+ *
+ * This type enables simple enrichment of `GenTraversableOnce`s with extension
+ * methods which can make full use of the mechanics of the Scala collections
+ * framework in their implementation.
+ *
+ * Example usage,
+ * {{{
+ * class FilterMapImpl[A, Repr](val r: GenTraversableOnce[A]) {
+ * final def filterMap[B, That](f: A => Option[B])(implicit cbf: CanBuildFrom[Repr, B, That]): That = {
+ * val b = cbf()
+ * for(e <- r.seq) f(e) foreach (b +=)
+ * b.result
+ * }
+ * }
+ * implicit def filterMap[Repr, A](r: Repr)(implicit fr: IsTraversableOnce[Repr]): FilterMapImpl[fr.A,Repr] =
+ * new FilterMapImpl[fr.A, Repr](fr.conversion(r))
+ *
+ * val l = List(1, 2, 3, 4, 5)
+ * List(1, 2, 3, 4, 5) filterMap (i => if(i % 2 == 0) Some(i) else None)
+ * // == List(2, 4)
+ * }}}
+ *
+ * @author Miles Sabin
+ * @author J. Suereth
+ * @since 2.10
+ */
+trait IsTraversableOnce[Repr] {
+ /** The type of elements we can traverse over. */
+ type A
+ /** A conversion from the representation type `Repr` to a `GenTraversableOnce[A]`. */
+ val conversion: Repr => GenTraversableOnce[A]
+}
+
+object IsTraversableOnce {
+ import language.higherKinds
+
+ implicit val stringRepr: IsTraversableOnce[String] { type A = Char } =
+ new IsTraversableOnce[String] {
+ type A = Char
+ val conversion = implicitly[String => GenTraversableOnce[Char]]
+ }
+
+ implicit def genTraversableLikeRepr[C[_], A0](implicit conv: C[A0] => GenTraversableOnce[A0]): IsTraversableOnce[C[A0]] { type A = A0 } =
+ new IsTraversableOnce[C[A0]] {
+ type A = A0
+ val conversion = conv
+ }
+}
+
View
8 src/library/scala/collection/generic/package.scala
@@ -6,12 +6,6 @@ import language.higherKinds
package object generic {
type CanBuild[-Elem, +To] = CanBuildFrom[Nothing, Elem, To]
- /** The type of conversions from a collection representation type
- * `Repr` to its corresponding GenTraversableLike.
- * @see [[scala.collection.generic.FromRepr]]
- */
- type HasElem[Repr, A] = Repr => GenTraversableLike[A, Repr]
-
@deprecated("use ClassTagTraversableFactory instead", "2.10.0")
type ClassManifestTraversableFactory[CC[X] <: Traversable[X] with GenericClassManifestTraversableTemplate[X, CC]] = ClassTagTraversableFactory[CC]
@@ -20,4 +14,4 @@ package object generic {
@deprecated("use GenericClassTagTraversableTemplate instead", "2.10.0")
type GenericClassManifestTraversableTemplate[+A, +CC[X] <: Traversable[X]] = GenericClassTagTraversableTemplate[A, CC]
-}
+}
View
4 test/files/run/enrich-gentraversable.check
@@ -2,3 +2,7 @@ List(2, 4)
Array(2, 4)
HW
Vector(72, 108, 108, 32, 114, 108, 100)
+List(2, 4)
+Array(2, 4)
+HW
+Vector(72, 108, 108, 32, 114, 108, 100)
View
81 test/files/run/enrich-gentraversable.scala
@@ -1,30 +1,67 @@
object Test extends App {
- import scala.collection.generic.{ CanBuildFrom, FromRepr, HasElem }
+ import scala.collection.{GenTraversableOnce,GenTraversableLike}
+ import scala.collection.generic._
def typed[T](t : => T) {}
-
- class FilterMapImpl[A, Repr](val r : Repr)(implicit hasElem : HasElem[Repr, A]) {
- def filterMap[B, That](f : A => Option[B])(implicit cbf : CanBuildFrom[Repr, B, That]) : That = r.flatMap(f(_).toSeq)
+ def testTraversableLike = {
+ class FilterMapImpl[A, Repr](val r: GenTraversableLike[A, Repr]) /* extends AnyVal */ {
+ final def filterMap[B, That](f: A => Option[B])(implicit cbf: CanBuildFrom[Repr, B, That]): That =
+ r.flatMap(f(_).toSeq)
+ }
+ implicit def filterMap[Repr, A](r: Repr)(implicit fr: IsTraversableLike[Repr]): FilterMapImpl[fr.A,Repr] =
+ new FilterMapImpl[fr.A, Repr](fr.conversion(r))
+
+ val l = List(1, 2, 3, 4, 5)
+ val fml = l.filterMap(i => if(i % 2 == 0) Some(i) else None)
+ typed[List[Int]](fml)
+ println(fml)
+
+ val a = Array(1, 2, 3, 4, 5)
+ val fma = a.filterMap(i => if(i % 2 == 0) Some(i) else None)
+ typed[Array[Int]](fma)
+ println(fma.deep)
+
+ val s = "Hello World"
+ val fms1 = s.filterMap(c => if(c >= 'A' && c <= 'Z') Some(c) else None)
+ typed[String](fms1)
+ println(fms1)
+
+ val fms2 = s.filterMap(c =>if(c % 2 == 0) Some(c.toInt) else None)
+ typed[IndexedSeq[Int]](fms2)
+ println(fms2)
}
+ def testTraversableOnce = {
+ class FilterMapImpl[A, Repr](val r: GenTraversableOnce[A]) /* extends AnyVal */ {
+ final def filterMap[B, That](f: A => Option[B])(implicit cbf: CanBuildFrom[Repr, B, That]): That = {
+ val b = cbf()
+ for(e <- r.seq) f(e) foreach (b +=)
- implicit def filterMap[Repr : FromRepr](r : Repr) = new FilterMapImpl(r)
-
- val l = List(1, 2, 3, 4, 5)
- val fml = l.filterMap(i => if(i % 2 == 0) Some(i) else None)
- typed[List[Int]](fml)
- println(fml)
-
- val a = Array(1, 2, 3, 4, 5)
- val fma = a.filterMap(i => if(i % 2 == 0) Some(i) else None)
- typed[Array[Int]](fma)
- println(fma.deep)
+ b.result
+ }
+ }
+ implicit def filterMap[Repr, A](r: Repr)(implicit fr: IsTraversableOnce[Repr]): FilterMapImpl[fr.A,Repr] =
+ new FilterMapImpl[fr.A, Repr](fr.conversion(r))
- val s = "Hello World"
- val fms1 = s.filterMap(c => if(c >= 'A' && c <= 'Z') Some(c) else None)
- typed[String](fms1)
- println(fms1)
+ val l = List(1, 2, 3, 4, 5)
+ val fml = l.filterMap(i => if(i % 2 == 0) Some(i) else None)
+ typed[List[Int]](fml)
+ println(fml)
- val fms2 = s.filterMap(c =>if(c % 2 == 0) Some(c.toInt) else None)
- typed[IndexedSeq[Int]](fms2)
- println(fms2)
+ val a = Array(1, 2, 3, 4, 5)
+ val fma = a.filterMap(i => if(i % 2 == 0) Some(i) else None)
+ typed[Array[Int]](fma)
+ println(fma.deep)
+
+ val s = "Hello World"
+ val fms1 = s.filterMap(c => if(c >= 'A' && c <= 'Z') Some(c) else None)
+ typed[String](fms1)
+ println(fms1)
+
+ val fms2 = s.filterMap(c =>if(c % 2 == 0) Some(c.toInt) else None)
+ typed[IndexedSeq[Int]](fms2)
+ println(fms2)
+ }
+
+ testTraversableLike
+ testTraversableOnce
}

0 comments on commit f40e521

Please sign in to comment.
Something went wrong with that request. Please try again.