4

我需要將任意嵌套的Map轉換爲TreeMap。例子:將地圖深層轉換爲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 [..]#結果沒有按」 t匹配我需要的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) 
    } 
} 

這工作,看起來完全合理的給我。