Skip to content

Instantly share code, notes, and snippets.

@ryanlecompte
Last active December 19, 2015 16:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryanlecompte/5988194 to your computer and use it in GitHub Desktop.
Save ryanlecompte/5988194 to your computer and use it in GitHub Desktop.
Deeply copying arbitrarily-deep nested arrays via type classes! (thanks for the typeclass idea from Erik Osheim)
trait Nested[A] {
def length(a: A): Int
def clone(a: A): A
}
object Nested {
implicit def nested[A] = new Nested[A] {
def length(a: A): Int = 1
def clone(a: A): A = a
}
implicit def nestedArray[A](implicit ev: Nested[A], mf: Manifest[A]) = new Nested[Array[A]] {
def length(as: Array[A]): Int = as.map { a => ev.length(a) }.sum
def clone(as: Array[A]): Array[A] = as.map { a => ev.clone(a) }
}
}
def deepCopy[A](array: Array[A])(implicit ev: Nested[Array[A]]): Array[A] = {
ev.clone(array)
}
// with above definitions imported into the REPL:
scala> val a = Array(Array(1,2,3), Array(4,5,6), Array(7,8,9))
a: Array[Array[Int]] = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9))
scala> val c = deepCopy(a)
c: Array[Array[Int]] = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9))
scala> a(0)(0) = 9999
scala> a
res1: Array[Array[Int]] = Array(Array(9999, 2, 3), Array(4, 5, 6), Array(7, 8, 9))
scala> c
res2: Array[Array[Int]] = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9))
@Mortimerp9
Copy link

just to make it more object like with postfix notation:

implicit class NestedArray[A](array: Array[A])(implicit ev: Nested[Array[A]]) {
    def deepCopy: Array[A] = ev.clone(array)
    def length: Int = ev.length(array)
}

val c = a.deepCopy

@ryanlecompte
Copy link
Author

Nice, Pierre!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment