4

임의의 중첩 된 Map을 TreeMap으로 변환해야합니다. 예 :Map을 TreeMap으로 심도 변환

Map[Int, String] -> TreeMap[Int, String] 
Map[Int, Map[Int, String]] -> TreeMap[Int, TreeMap[Int, String]] 
... etc 

내가 그러나 내가 유형

trait ToTreeMap[M[_, _], K, V] { 
    type Result 

    def treeMap(x: M[K, V]): TreeMap[K, Result] 
} 

trait LowerPriorityToTreeMap { 
    implicit def plainMap[K, V](implicit ord: Ordering[K]): ToTreeMap[Map, K, V] = 
    new ToTreeMap[Map, K, V] { 
     type Result = V 

     def treeMap(x: Map[K, V]): TreeMap[K, Result] = TreeMap(x.toArray: _*) 
    } 
} 

object ToTreeMap extends LowerPriorityToTreeMap { 
    implicit def nestedMap[K1, K2, V](implicit inner: ToTreeMap[Map, K2, V], ord: Ordering[K1]): ToTreeMap[Map, K1, Map[K2, V]] = { 
    new ToTreeMap[Map, K1, Map[K2, V]] { 
     type Result = TreeMap[K2, inner.Result] 

     def treeMap(x: Map[K1, Map[K2, V]]): TreeMap[K1, Result] = TreeMap(x.mapValues(v => inner.treeMap(v)).toArray: _*) 
    } 
    } 

    implicit class MapOps[K, V](map: Map[K, V]) { 
    def asTreeMap(implicit as: ToTreeMap[Map, K, V]) = as.treeMap(map) 
    } 
} 

이 잘 작동에 문제가 입력 체조 및 암시 적 변환과 솔루션을 일하고있어 한, 그러나 ToTreeMap가 [..] # 결과는 '아무튼 입력 필요로하는 TreeMap과 일치하지 않습니다.

import ToTreeMap._ 

    val map: Map[Int, Map[Int, Map[Int, String]]] = 
    Map(
     1000 -> Map(
     100 -> Map(
      10 -> "aa", 
      1 -> "bb" 
     ), 
     99 -> Map(
      10 -> "aa", 
      1 -> "bb" 
     ) 
    ), 
     999 -> Map(
     100 -> Map(
      10 -> "aa", 
      1 -> "bb" 
     ), 
     99 -> Map(
      10 -> "aa", 
      1 -> "bb" 
     ) 
    ) 
    ) 

    val m = Map(1 -> "aaa") 

    println(map.asTreeMap) 
    println(m.asTreeMap) 

    // This line fails to compile 
    val tm: TreeMap[Int, TreeMap[Int, TreeMap[Int, String]]] = map.asTreeMap 

좋은 아이디어가 있습니까?

Scalac이 예제에서는 올바른 유형을 선택합니다 : Two dimensional array as a function을 나는

내가 'asIntanceOf'로 이러한 유형의 문제를 해결할 수 있지만이 더러운없이 그렇게하고 싶은 생각으로이 일에서 너무 많은 차이가있는 마구 자르기.

답변

4

당신은 당신의 인스턴스 메서드 '반환 형식에 Return 값을 던져하지 않도록주의해야합니다

trait ToTreeMap[M[_, _], K, V] { 
    type Result 

    def treeMap(x: M[K, V]): TreeMap[K, Result] 
} 

trait LowerPriorityToTreeMap { 
    implicit def plainMap[K, V](
    implicit ord: Ordering[K] 
): ToTreeMap[Map, K, V] { type Result = V } = 
    new ToTreeMap[Map, K, V] { 
     type Result = V 

     def treeMap(x: Map[K, V]): TreeMap[K, Result] = TreeMap(x.toArray: _*) 
    } 
} 

object ToTreeMap extends LowerPriorityToTreeMap { 
    implicit def nestedMap[K1, K2, V](
    implicit inner: ToTreeMap[Map, K2, V], ord: Ordering[K1] 
): ToTreeMap[Map, K1, Map[K2, V]] { 
    type Result = TreeMap[K2, inner.Result] 
    } = { 
    new ToTreeMap[Map, K1, Map[K2, V]] { 
     type Result = TreeMap[K2, inner.Result] 

     def treeMap(x: Map[K1, Map[K2, V]]): TreeMap[K1, Result] = 
     TreeMap(x.mapValues(v => inner.treeMap(v)).toArray: _*) 
    } 
    } 

    implicit class MapOps[K, V](map: Map[K, V]) { 
    def asTreeMap(implicit as: ToTreeMap[Map, K, V]) = as.treeMap(map) 
    } 
} 

이 작동하고, 나에게 완벽하게 합리적으로 보인다.