2012-03-15 2 views
5

の値をキーでグループ化する方法mergeKeysを書きたいと思います。例えば、私は書くことができます:Monoidでキーを使って値をグループ化する

def mergeKeysList[K, V](iter: Iterable[(K, V)]) = { 
    iter.foldLeft(Map[K, List[V]]().withDefaultValue(List.empty[V])) { 
     case (map, (k, v)) => 
      map + (k -> (v :: map(k))) 
    } 
    } 

しかし、私はListするための方法を書くのではなく、任意のMonoidを使用できるようにしたいと思います。たとえば、値は整数で、リストに追加するのではなく、それらを合計したいとします。または、私は文字列を累積して整数にするタプル(String, Int)かもしれません。どのように私はそのような方法を書くことができますか?それとも、これを行うために私がscalazで使うことができる何か他にありますか?

更新:私は思ったほど遠くはありませんでした。私はちょっと近づいてきましたが、値がタプルであればそれを動作させる方法はまだ分かりません。私はもう一つの暗黙の変換を書く必要がありますか?つまり、型パラメータの数ごとに1つの暗黙的な変換ですか?

sealed trait SuperTraversable[T, U, F[_]] 
extends scalaz.PimpedType[TraversableOnce[(T, F[U])]] { 
    def mergeKeys(implicit mon: Monoid[F[U]]): Map[T, F[U]] = { 
    value.foldLeft(Map[T, F[U]]().withDefaultValue(mon.zero)) { 
     case (map, (k, v)) => 
     map + (k -> (map(k) |+| v)) 
    } 
    } 
} 

implicit def superTraversable[T, U, F[_]](
    as: TraversableOnce[(T, F[U])] 
): SuperTraversable[T, U, F] = 
    new SuperTraversable[T, U, F] { 
     val value = as 
    } 

答えて

6

まず、それはあなたの質問に関係ないですが、あなたは明示的に型コンストラクタF[_]を言及することで、あなたのコードの 一般性を制限しています。それはそうせずに 正常に動作します:

sealed trait SuperTraversable[K, V] 
extends scalaz.PimpedType[TraversableOnce[(K, V)]] { 
    def mergeKeys(implicit mon: Monoid[V]): Map[K, V] = { 
     value.foldLeft(Map[K, V]().withDefaultValue(mon.zero)) { 
      case (map, (k, v)) => 
       map + (k -> (map(k) |+| v)) 
     } 
    } 
} 

[...] 

は今、あなたの実際の質問のために、組み合わせの 面白いの種類を処理するためにmergeKeysを変更する必要はありません。どのような種類の を処理する場合は、Monoidと書いてください。

implicit def monoidStringInt = new Monoid[(String, Int)] { 
    val zero = ("", 0) 
    def append(a: (String, Int), b: => (String, Int)) = (a, b) match { 
     case ((a1, a2), (b1, b2)) => (a1 + b1, a2 + b2) 
    } 
} 

println { 
    List(
     "a" -> ("Hello, ", 20), 
     "b" -> ("Goodbye, ", 30), 
     "a" -> ("World", 12) 
    ).mergeKeys 
} 

Map(a -> (Hello, World,32), b -> (Goodbye, ,30)) 
+0

パーフェクトを与え、感謝:あなたの文字列+ int型の例をやってみたかったと言います! – schmmd

関連する問題