Управление гибкими, типизированными, неизменяемыми структурами данных в Scala версии 2.8.x

Это продолжение того, что бета-версия Scala 2.8.0 не отвечает на этот вопрос:

Что такое правильный как управлять гибкими, типизированными, неизменяемыми структурами данных в Scala?

Новый метод заключается в копировании класса case, например.

case class Person(name:String, email:String)

val bob = Person("Bob", "[email protected]")
val jill = bob.copy(name = "Jill")

Это прекрасно работает, за исключением того факта, что Scala, похоже, ограничивает меня 22 (?) свойствами в классе case. Это может показаться много, в моем случае этого недостаточно.

С 23 я получаю: «ошибка: тип Function23 не является членом пакета scala». Возможно, я мог бы определить свою собственную функцию Function23 и т. д., но я не знаю последствий этого.

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

22 здесь кажется довольно произвольным пределом. Это можно обойти?

Это для импорта данных, который выглядит примерно так:

new CatalogImportRecord() {
    override val List(SVal(vendorSku), SVal(title), IVal(issues),
      _, // YToMVal(termMonths),
      DVal(sellPrice), DVal(buyPrice), DVal(retailPrice), NotesVal(allowsNew, allowsRenewals),
      _) //DateValMdy(lastUpdated))
      = fields

Как видите, я закомментировал неиспользуемые извлечения, чтобы уменьшить количество полей.

Может быть, есть лучший способ сделать это. Я нахожу эту технику извлечения немного жесткой, но это может быть и к лучшему.


person Alex Neth    schedule 09.02.2010    source источник
comment
Я не синтезирую программно. Это внутреннее отражение импортируемой записи с множеством полей. Группировка связанных полей сделала бы мой код извлечения довольно уродливым. @Rex, не обижайся, но этот пример некрасивый. На данный момент я сократил количество полей, но это кажется довольно глупым ограничением для языка... Я отчаянно пытаюсь избежать общих хеш-таблиц и на данный момент.... Добавлен пример кода импорта выше.   -  person Alex Neth    schedule 09.02.2010
comment
@Rex хотел сказать, что код, который генерирует классы Product - причина вашего текущего прогноза - генерируется автоматически. Он предлагает вам сгенерировать новую библиотеку с другими настройками, что, кстати, действительно является единственной альтернативой, если вы собираетесь использовать классы case.   -  person Daniel C. Sobral    schedule 09.02.2010


Ответы (3)


Код генерируется автоматически, так что вы можете перекомпилировать библиотеку Scala (с измененными настройками), если собираетесь использовать проект только самостоятельно.

Если вы печатаете более 23 элементов вручную в классах прецедентов, рассмотрите возможность группировки значений любым удобным способом — используйте кортежи для группировки элементов, которые имеют смысл вместе, или используйте подклассы прецедентов для более тесной группировки элементов. Это сделает обновление немного более неудобным, но если вы сгруппируете вещи, которые необходимо обновить, это должно помочь.

Например, попробуйте это в Scala 2.8:

((1,2,3,4,5,6,7,8,9),(1,2,3,4,5,6),(1,2,3,4,5,6,7,8,9)).copy(_2=(4,5,6,7,8,9))

Если у вас уже есть оригинал в val, еще проще изменить только одну вещь:

val a = (1,2,(1,2))
a.copy(_3=a._3.copy(_1=3))
person Rex Kerr    schedule 09.02.2010
comment
Я не знаю о кортежах - a.copy(_3=a._3.copy(_1=3)) заставит многих людей работать, но, возможно, подклассы - хорошее решение. - person Alex Neth; 09.02.2010
comment
Кортежи — это просто предопределенные классы case. С вашим собственным кодом все гораздо понятнее — он будет больше похож на record.copy(customer=record.customer(lastname="Smith")). - person Rex Kerr; 09.02.2010

См. genprod.scala в каталоге src/build, измените его, используйте для генерации нужной арности, а затем перекомпилируйте библиотеку. Вам, вероятно, потребуется сохранить модифицированную библиотеку Scala.

Возможно, эти дополнительные классы можно разделить, скомпилировать и сохранить в другом файле jar. Я не знаю, но, думаю, стоило бы попробовать.

Или используйте карту вместо класса случая.

person Daniel C. Sobral    schedule 09.02.2010
comment
Спасибо за предложение. Я не хочу использовать карту (потерять безопасность типов, что составляет половину смысла Scala). Я также не хочу хранить свою собственную базовую библиотеку scala. В нынешнем виде я просто уменьшил количество полей. Это странное ограничение языка... Однако в целом Scala 2.8 представляет собой значительное улучшение удобства использования с параметрами по умолчанию и именованными параметрами. - person Alex Neth; 10.02.2010

Вы пишете эти гигантские кейс-классы вручную?

Если вы синтезируете их программно, вы всегда можете воспроизвести то, что делает компилятор для классов case, и получить практически тот же результат без ограничения Product22. Все, что он делает для классов case, имеет эквивалент в исходном коде Scala для класса без case.

person Randall Schulz    schedule 09.02.2010
comment
Я бы не сказал, что они гигантские... и это всего лишь один класс. Но мне не нравится идея написания конструктора и метода копирования для синхронизации. - person Alex Neth; 09.02.2010