Как применить шаблон enrich-my-library к коллекциям Scala?

Один из самых мощных шаблонов, доступных в Scala, - это шаблон шаблон enrich-my-library *, который использует неявные преобразования в , появляются для добавления методов в существующие классы без необходимости динамического разрешения методов. Например, если бы мы хотели, чтобы все строки имели метод пробелы , который подсчитывает, сколько в них пробелов, мы могли бы:

class SpaceCounter(s: String) {
  def spaces = s.count(_.isWhitespace)
}
implicit def string_counts_spaces(s: String) = new SpaceCounter(s)

scala> "How many spaces do I have?".spaces
res1: Int = 5

К сожалению, этот шаблон вызывает проблемы при работе с универсальными коллекциями. Например, был задан ряд вопросов о группировке элементов последовательно с коллекциями . В нем нет ничего встроенного, что работало бы за один раз, поэтому это кажется идеальным кандидатом для шаблона обогащения моей библиотеки с использованием общей коллекции C и универсального типа элемента A :

class SequentiallyGroupingCollection[A, C[A] <: Seq[A]](ca: C[A]) {
  def groupIdentical: C[C[A]] = {
    if (ca.isEmpty) C.empty[C[A]]
    else {
      val first = ca.head
      val (same,rest) = ca.span(_ == first)
      same +: (new SequentiallyGroupingCollection(rest)).groupIdentical
    }
  }
}

кроме, конечно, не работает . REPL сообщает нам:

:12: error: not found: value C
               if (ca.isEmpty) C.empty[C[A]]
                               ^
:16: error: type mismatch;
 found   : Seq[Seq[A]]
 required: C[C[A]]
                 same +: (new SequentiallyGroupingCollection(rest)).groupIdentical
                      ^

Есть две проблемы: как получить C [C [A]] из пустого списка C [A] (или из воздуха )? И как получить C [C [A]] обратно из той же строки +: вместо Seq [Seq [A]] ?

* Ранее известный как pimp-my-library.

92
задан Community 23 May 2017 в 11:46
поделиться