7

Scala の不変のプリンシパルにとどまることを学習する際に、多くの問題に遭遇するようです。その 1 つは、問題のオブジェクトからの複製 (または派生) の概念です。

これらの問題の 1 つは、特性の混合の概念です - 例

trait helper //modifies some kind behavior.. assume we want to to continue down the line

class A (val x:int) {

 def add(y:int) = new A(x + y)
}

Example extends App {

 val a =new A(5) with helper
 val b = a.add(10)  // mixed trait disappears

}

これは、さまざまなクラス、クラス A を非表示にするファクトリ メソッドなどについて、今日すでに作成した、より複雑な問題の本当に単純なバージョンです。1 つのトレイトのみを扱う場合は、単純にテストして必要に応じて転送します。しかし、3つ以上の特性が存在する可能性がある場合、一体どうすればよいでしょうか? 非現実的なすべての組み合わせをテストする必要があります。

さまざまな特性を持つ既存のオブジェクトをどのようにインスタンス化 (クローン) したり、機能設計の原則を順守しながら、その一部の側面を変更したりしますか?

どうもありがとう - ティム

4

1 に答える 1

3

コレクションは、最初から対象の型を生成する方法を知っている暗黙のビルダーを使用します。これらの 2 つのタイプは、必ずしも同じものではありません。

生成できるものを制御するタイプセーフ ビルダーに関する関連記事が多数あります

関連する質問は、混合型のコレクションがある場合はどうなるかです: 不変のクラス階層でのポリモーフィックな更新

値の軸では、型をエンコードする代わりに値を追跡 する Java ビルダー パターンに相当する Scala は何ですか?

更新: プレイ中に似たようなことが起きました。パターンでの RE の使用については、ML とこちらで説明されています。

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

型パラメーターを使用して暗黙を制御する使用法と代替手段を使用します。

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"
  }
}
于 2013-06-24T00:34:31.813 に答える