Я решил добавить еще один ответ из-за совершенно другого подхода.
Вы можете, на самом деле, не обернуть правильно напечатанные карты с огромными обходными решениями. Я не очень хорош в этом, поэтому его можно было бы упростить.
Trick - это создание последовательности типизированных функций, которая в последнее время производит многоуровневую карту с использованием type classes
и type path
.
Так вот решение
sealed trait KeySeq[-V] {
type values
}
case class KeyNil[V]() extends KeySeq[V] {
type values = Seq[V]
}
case class KeyCons[K, V, Next <: KeySeq[V]](f: V => K, next: Next)
(implicit ev: RecGroup[V, Next]) extends KeySeq[V] {
type values = Map[K, Next#values]
def #:[K1](f: V => K1) = new KeyCons[K1, V, KeyCons[K, V, Next]](f, this)
}
trait RecGroup[V, KS <: KeySeq[V]] {
def group(seq: Seq[V], ks: KS): KS#values
}
implicit def groupNil[V]: RecGroup[V, KeyNil[V]] = new RecGroup[V, KeyNil[V]] {
def group(seq: Seq[V], ks: KeyNil[V]) = seq
}
implicit def groupCons[K, V, Next <: KeySeq[V]](implicit ev: RecGroup[V, Next]): RecGroup[V, KeyCons[K, V, Next]] =
new RecGroup[V, KeyCons[K, V, Next]] {
def group(seq: Seq[V], ks: KeyCons[K, V, Next]) = seq.groupBy(ks.f) mapValues (_ groupRecursive ks.next)
}
implicit def funcAsKey[K, V](f: V => K): KeyCons[K, V, KeyNil[V]] =
new KeyCons[K, V, KeyNil[V]](f, KeyNil[V]())
implicit class GroupOps[V](coll: Seq[V]) {
def groupRecursive[KS <: KeySeq[V]](ks: KS)(implicit g: RecGroup[V, KS]) =
g.group(coll, ks)
}
ключевые функции состоят через #:
правоассоциативной оператор
так, если мы определим
def mod(m:Int) = (x:Int) => x % m
def even(x:Int) = x % 2 == 0
затем
1 to 30 groupRecursive (even _ #: mod(3) #: mod(5))
дал бы Map[Boolean,Map[Int,Map[Int,Int]]]
!!!
и если из предыдущего вопроса мы хотели бы
users.groupRecursive(((u:User)=> u.city(0)) #: ((u:User) => month(u.birthDate)))
Мы строим Map[Char,Map[String,User]]
!
Удивительно! Не имел представления о рекурсивных типах. Большое спасибо. – Armin