Скопируйте объекты в Scala, но изменив «детей» для переписывания - PullRequest
1 голос
/ 15 сентября 2010

В 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)

Ответы [ 2 ]

3 голосов
/ 15 сентября 2010

Я использую модифицированную версию модуля Kiama Rewriter.Он добавляет черту Constructable, которая означает, что значение может deconstruct само по себе (создать массив, содержащий его компоненты / потомки) и reconstruct новый экземпляр из массива компонентов.Когда Kiama встречает значение, которое реализует Constructable в одном из методов dup, child, all или some, оно избегает отражающего кода и вместо этого использует deconstruct и construct.

Помимо освобождения клиентского кода от требования, согласно которому типы, поддающиеся перезаписи, должны быть получены из Product, он допускает гетерогенное переписывание.Другими словами, тип, выходящий из перезаписи, не обязательно должен быть точно идентичным конкретному типу значения, которое было переписано.

Недостатком является то, что клиентский код должен определять эти deconstruct и construct методов.

(И, наконец, я не совсем уместен в вашем вопросе, я добавил оптимизацию, которая позволяет избежать создания нового значения, если результат преобразования вспомогательных значений (неатомарных) был равеноригинал. Я добавил это только в ветке, которая обрабатывает Constructable с.)

1 голос
/ 19 сентября 2010

Я создал небольшой репозиторий GitHub, RSchulz / sbtr , содержащий мой модифицированный модуль Kiama Rewriter.scala.В нем вы найдете следующие файлы:

  • src/main/scala/rrs/sbtr/SBTR.scala - Мой модуль «Переопределение терминов на основе стратегии»
  • src/main/scala/rrs/sbtr/RewriterFmt.alacs - Исходный код после форматирования для моих соглашений стиля
  • src/main/scala/rrs/sbtr/Rewriter-0.8.alacs - слегка обновленная версия 0.8
  • src/main/scala/rrs/sbtr/Rewriter.alacs - оригинальная версия, с которой я начал

Различение первых двух раскроет мои модификации, который должен быть легко перенесен в текущий код Kiama Rewriter.scala.

Основное различие между исходной и 0,8 версиями исходного кода Rewriter.scala заключается в добавлении queryf, что я и сделалперенести в SBTR.Изменения после 0,8 не были включены.

Суффикс .alacs (scala пишется в обратном направлении) используется для предотвращения компиляции этих файлов.Насколько мне известно, инструменты сборки и IDE не могут быть направлены на игнорирование определенных файлов (по крайней мере, не легко).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...