The collections use implicit builders who know how to create a target type from where you start. These two types are not always the same.
There are many related posts about collector types that control what can be created, for example, http://nullary.blogspot.com/2011/10/builder-pattern-revisited-in-scala.html
Related question: if you have a collection of mixed types: Polymorphic updates in an immutable class hierarchy
On the value axis, tracking values ββinstead of coding types What is Scala equivalent to the Java builder pattern?
Updated: Something similar just appeared during the game. The use of RE in templates is described in ML and here .
package object interpat { implicit class MySContext (val sc : StringContext) { object mys { def apply (args : Any*) : String = sc.s (args : _*) def unapplySeq (s : String) : Option[Seq[String]] = { val regexp = sc.parts.mkString ("(.+)").r regexp.unapplySeq (s) } } } implicit class SBContext (val sc : StringContext) { def sb(args: Any*): SB = new SB(sc.s (args : _*)) } implicit class toHasPattern(sb: SB) { def /(pp: String) = new SB(sb.s) with HasPattern { val p = pp } } implicit class toHasRepl(hasp: SB with HasPattern) { def /(rr: String) = new SB(hasp.s) with HasPattern with HasRepl with Updateable { val p = hasp.p val r = rr } }
Using and an alternative to managing implications with type parameters.
package interpat { import scala.util.Try object I { def unapply(x: String): Option[Int] = Try(x.toInt).toOption } trait XX { type HasIt type Yes <: HasIt type No <: HasIt } object XX extends XX { implicit class XContext (val sc : StringContext) { def x(args: Any*) = new X[No, No] { val s = sc.s(args : _*) } } implicit class xPat(x: X[No, No]) { def /(pp: String) = new X[Yes, No] with HasPattern { val s = xs val p = pp } } implicit class xRep(x: X[Yes, No] with HasPattern) { def /(rr: String) = new X[Yes, Yes] with HasPattern with HasRepl { val s = xs val p = xp val r = rr override def toString = s replaceAll (p, r ) } } implicit class xable(xx: X[Yes, Yes]) { def x = xx.toString } } import XX._ trait X[HasP <: HasIt, HasR <: HasIt] { def s: String } trait HasPattern { def p: String } trait HasRepl { def r: String } trait Updateable { this: HasPattern with HasRepl => def update(p: String, r: String) override def toString = { update(p, r) super.toString } } class SB(val s: String) { final val sb = new StringBuilder(s) def update(p: String, r: String): Unit = sb.replace(0, sb.length, sb.toString.replaceAll(p, r)) override def toString = sb.toString } object Test extends App { val msg = "The sky is blue" match { case mys"The $thing is $colour" => mys"A $colour thing is $thing" case _ => "no match" } println (msg) val mys"The $thing is $colour" = "The sky is blue" Console println s"$thing / $colour" val mys"The ${I(number)} is blue" = "The 3 is blue" Console println s"$number" //sb"The sky is blue".update("blue","red") // no way to get a value out! sb"The sky is blue"("blue") = "red" val ugh = sb"The sky is blue" ugh("blue") = "red" Console println ugh val sx = sb"The sky is $colour" / "blue" / "red" Console println sx //sb"The sky is $colour" / "blue" / "red" / "yellow" Console println sx Console println x"The sky is $colour" / "blue" / "red" Console println (x"The sky is $colour" / "blue" / "red").x //Console println x"The sky is $colour" / "blue" / "red" / "yellow" } }
som-snytt
source share