Есть ли простой способ использования системы типов Scala и, в идеале, без дополнительных затрат времени выполнения для обеспечения строгих коллекций? Мне бы понравилось что-то вроде приведенного ниже, но, просматривая API коллекций Scala, я не вижу такой иерархии. Я бы предпочел не использовать белый список строгих коллекций, но если это единственный способ, я буду жить с ним.
case class Foo(xs: immutable.StrictSeq[Int])
Проблема в том, что у меня есть древовидная структура с несколькими последовательностями в ключевом общедоступном API. Обычный шаблон, который люди используют для извлечения информации из него, - это рекурсивный обход структуры и заполнение изменяемых структур данных. Если вы затем случайно вставите ленивую коллекцию в дерево, ничего не получится. Шаблон сомнительный, но широко используемый, поэтому моя цель - найти способ предотвратить попадание людей в ногу.
Scala Seq
не собирает достаточно информации, чтобы решить, являются ли они строгими или нет.
Вы можете внести в белый список последовательности, которые вы примете, следующим образом:
import scala.language.higherKinds
// Tag for sequences that are strict.
sealed trait StrictSeq[T[_] <: Seq[_]]
object StrictSeq {
// Evidence for the compiler that lists and vectors are strict.
implicit object ListIsStrict extends StrictSeq[List]
implicit object VectorIsStrict extends StrictSeq[Vector]
}
// Restrict S to be a sequence and to have been tagged as strict.
case class Foo[S[_] <: Seq[_] : StrictSeq](xs: S[Int])
Foo(List(1, 2, 3)) // OK
Foo(Vector(1, 2, 3)) // OK
Foo(Stream(1, 2, 3)) // Compile-time error
Какую большую проблему вы пытаетесь решить? Обычно, если меня беспокоит, что вызывающие абоненты изменяют сохраненную коллекцию, я просто создаю ее неизменяемую копию внутри и использую ее.