Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added infrastructure to enable easy enrichment of GenTraversables.
- Loading branch information
1 parent
ce896d6
commit 73f7001
Showing
5 changed files
with
105 additions
and
0 deletions.
There are no files selected for viewing
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 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* __ *\ | ||
** ________ ___ / / ___ 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 `GenTraversableLike[A, Repr]`. | ||
* | ||
* This type enables simple enrichment of `GenTraversable`s with extension | ||
* methods which can make full use of the mechanics of the Scala collections | ||
* framework in their implementation. | ||
* | ||
* 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) | ||
* } | ||
* | ||
* implicit def filterMap[Repr : FromRepr](r : Repr) = new FilterMapImpl(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 | ||
* @since 2.10 | ||
*/ | ||
trait FromRepr[Repr] { | ||
type A | ||
val hasElem: HasElem[Repr, A] | ||
} | ||
|
||
object FromRepr { | ||
import language.higherKinds | ||
|
||
implicit val stringFromRepr : FromRepr[String] { type A = Char } = new FromRepr[String] { | ||
type A = Char | ||
val hasElem = implicitly[HasElem[String, Char]] | ||
} | ||
|
||
implicit def genTraversableLikeFromRepr[C[_], A0] | ||
(implicit hasElem0: HasElem[C[A0], A0]) : FromRepr[C[A0]] { type A = A0 } = new FromRepr[C[A0]] { | ||
type A = A0 | ||
val hasElem = hasElem0 | ||
} | ||
} |
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 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
List(2, 4) | ||
Array(2, 4) | ||
HW | ||
Vector(72, 108, 108, 32, 114, 108, 100) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
object Test extends App { | ||
import scala.collection.generic.{ CanBuildFrom, FromRepr, HasElem } | ||
|
||
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) | ||
} | ||
|
||
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) | ||
|
||
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) | ||
} |