Skip to content

Instantly share code, notes, and snippets.

@retronym
Created February 14, 2010 12:02
Show Gist options
  • Select an option

  • Save retronym/303975 to your computer and use it in GitHub Desktop.

Select an option

Save retronym/303975 to your computer and use it in GitHub Desktop.
Collection Conversions with ==>> implicit
trait ==>>[-A, +B] extends (A => B) {
self =>
def apply(a: A): B
def map[C](f: B => C) = new (A ==>> C) {
def apply(a: A) = f(self.apply(a))
}
def comap[C](f: C => A) = new (C ==>> B) {
def apply(c: C) = self.apply(f(c))
}
}
object ==>> {
def convert[A, B](a: A)(implicit a2b: A ==>> B): B = a
// the default identity conversion
implicit def Identity_==>>[A] = new (A ==>> A) {
def apply(a: A) = a
}
def lift[A, B](a2b: A => B): A ==>> B = new (A ==>> B) {
def apply(a: A) = a2b(a)
}
// import whichever conversions you like from here:
object Conversions {
import java.{util => ju}
import ju.{ArrayList, HashMap}
import collection.mutable.Buffer
import collection.JavaConversions._
implicit def JavaListToScalaBuffer[T, U](implicit t2u: T ==>> U) = lift {a: ju.List[T] => asBuffer(a).map(t2u)}
implicit def JavaListToScalaList[T, U](implicit t2u: T ==>> U) = JavaListToScalaBuffer(t2u) map (_.toList)
implicit def JavaMapToMap[K, V, VV](implicit v2vv: V ==>> VV) = lift {a: ju.Map[K, V] => asMap(a).mapValues(v2vv): collection.Map[K, VV]}
implicit def JavaMapToImmutableMap[K, V, VV](implicit v2vv: V ==>> VV) = JavaMapToMap(v2vv) map {m: collection.Map[K, VV] => Map(m.toSeq: _*)}
implicit def JavaIntegerToInt = lift {(_: java.lang.Integer).intValue}
}
}
object test {
def main(args: Array[String]) {
import java.util.{ArrayList, HashMap}
import collection.mutable.Buffer
// some java collections with different nesting
val javaMutable1 = new HashMap[String, ArrayList[ArrayList[Double]]]
val javaMutable2 = new HashMap[String, ArrayList[HashMap[String, ArrayList[ArrayList[Double]]]]]
val javaBoxedInt = new HashMap[String, ArrayList[ArrayList[java.lang.Integer]]]
// here comes the elegant part!
import ==>>.{convert, Conversions}
{
import Conversions.{JavaMapToMap, JavaListToScalaBuffer}
val scala1 = convert(javaMutable1)
val scala2 = convert(javaMutable2)
// check the types to show that the conversion worked.
scala1: collection.Map[String, Buffer[Buffer[Double]]]
scala2: collection.Map[String, Buffer[collection.Map[String, Buffer[Buffer[Double]]]]]
}
{
import Conversions.{JavaMapToImmutableMap, JavaListToScalaList, JavaIntegerToInt}
val scala1 = convert(javaMutable1)
val scala2 = convert(javaMutable2)
val scala3 = convert(javaBoxedInt)
// check the types to show that the conversion worked.
scala1: Map[String, List[List[Double]]]
scala2: Map[String, List[Map[String, List[List[Double]]]]]
scala3: Map[String, List[List[Int]]]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment