コレクションあなたが開始しているものから、ターゲット・タイプを生成する方法を知っている暗黙のビルダーを使用しています。これら2つのタイプは必ずしも同じものではありません。
例えば製造することができるかを制御タイプセーフビルダー、およそ多くの関連記事がありますが、 http://nullary.blogspot.com/2011/10/builder-pattern-revisited-in-scala.html
関連する質問で何を混在型のコレクションがある場合:値に Polymorphic updates in an immutable class hierarchy
を軸、符号化タイプの代わりにトラッキング値 What is the Scala equivalent to a Java builder pattern?
更新:再生時に類似したものがありました。パターンにREを使用することについては、MLおよび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
}
}
// disallow it
implicit class noway(hasr: SB with HasPattern with HasRepl) {
def /(rr: String) = ???
}
implicit class noway2(hasr: SB with HasPattern with HasRepl) {
def /(rr: String) = ???
}
}
タイプパラメータでimplicitsを制御する方法と代替方法を使用します。
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 = x.s
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 = x.s
val p = x.p
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"
}
}
これはまったく簡単なことです。これは私がケーキパターンを避けようとする主な理由の1つです。同じケーキを作り直すのは本当に面倒です。振る舞いを変更するものがデータ(例えば、おそらくコンストラクタ内のクラスの 'val')であれば一般的に簡単です。 –
私は同意して悲しげに私がこのパターンを飾る特性を避け続けるのは同然です...それは本の中ではすばらしいようですが、ここで概説したように、後でオブジェクトをクローンする方法については学問の本では決して言及しません。 – LaloInDublin
基本的には、オブジェクトのビルダーを作成しなければなりません。このビルダーでは、特性を混在させるたびに別の3〜4行の定型文を追加します。時にはまだ価値があります。しばしばそうではありません。 –