В kiama общий метод "dup" определяется , который копирует Product
объектов и применяет данную функцию к каждому из элементов Product
для поддержки переписывание Term
s:
/**
* General product duplication function. Returns a product that applies
* the same constructor as the product t, but with the given children
* instead of t's children. Fails if a constructor cannot be found or
* if one of the children is not of the appropriate type.
*/
private def dup (t : Product, children : Array[AnyRef]) : Product = {
val ctor = (t.getClass.getConstructors())(0)
try {
val ret = ctor.newInstance (children : _*).asInstanceOf[Product]
ret
} catch {
case e : java.lang.ClassCastException =>
error ("dup cast failed: " + t)
case e : IllegalArgumentException =>
error ("dup illegal arguments: " + ctor + " (" +
children.deep.mkString (",") + "), expects " +
ctor.getParameterTypes.length)
}
}
Используется как это :
private def childProduct (p : Product, i : Int, s : => Strategy) : Option[Term] = {
val numchildren = p.productArity
val ct = p.productElement (i-1)
val children = new Array[AnyRef](numchildren)
for (j <- 0 until numchildren)
children (j) = makechild (p.productElement (j))
s (ct) match {
case Some (ti) =>
children (i-1) = makechild (ti)
case None =>
return None
}
val ret = dup (p, children)
Some (ret)
Это дает некоторые ограничения по использованию.
Я знаю, что они работают над заменой этого механизма ( Выпуск 2 , Выпуск 31 ), но я думаю, что было бы интересно услышать, как вы, ребята, сделаете это?
Например, Positional
var (или любой другой var!) Комбинаторов анализатора scala не будет скопирован. На самом деле все, что не является частью первого конструктора explict (и, следовательно, компилятора по умолчанию, генерирует метод unapply
).
Я экспериментировал с предоставлением какой-то черты или подобного, которую я мог бы добавить к моим терминам, которые могли бы использовать методы dup / childProduct / etc, но пока не повезло. (Я не понимаю, как можно использовать класс case copy
)