Предположим, я хочу добавить функциональность типа map
в Scala List
, что-то вдоль строк list mapmap f
, которая дважды применяет функцию f
к каждому элементу List
. (Более серьезным примером может быть реализация параллельной или распределенной карты, но я не хочу отвлекаться на детали в этом направлении.)
Мой первый подход был бы
object MapMap {
implicit def createFancyList[A](list: List[A]) = new Object {
def mapmap(f: A => A): List[A] = { list map { a: A => f(f(a)) } }
}
}
теперь это отлично работает
scala> import MapMap._
import MapMap._
scala> List(1,2,3) mapmap { _ + 1 }
res1: List[Int] = List(3, 4, 5)
за исключением, конечно, только для List
s, и нет причин, по которым мы не хотим, чтобы это работало на что-либо Traverseable
, с функцией map
, например. Set
или Stream
s. Итак, вторая попытка выглядит как
object MapMap2 {
implicit def createFancyTraversable[A](t: Traversable[A]) = new Object {
def mapmap(f: A => A): Traversable[A] = { t map { a: A => f(f(a)) } }
}
}
Но теперь, конечно, результат не может быть присвоен List[A]
:
scala> import MapMap2._
import MapMap2._
scala> val r: List[Int] = List(1,2,3) mapmap { _ + 1 }
<console>:9: error: type mismatch;
found : Traversable[Int]
required: List[Int]
Есть ли какая-то средняя земля? Могу ли я написать неявное преобразование, которое добавляет метод ко всем подклассам Traversable и успешно возвращает объекты с этим типом?
(Я предполагаю, что это подразумевает понимание ужасной черты CanBuildFrom
и, возможно, даже breakout
!)