Last active
August 29, 2015 13:57
-
-
Save manjuraj/9492759 to your computer and use it in GitHub Desktop.
Clever use of typeclasses to enrich existing type while preserving existing type in type system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Type information got lost because of implicit conversion - instead of type | |
// Array[T], we have the runtime type WrappedArray[T] | |
scala> def first[T](x: Traversable[T]) = (x.head, x) | |
first: [T](x: Traversable[T])(T, Traversable[T]) | |
scala> first(Array(1,2,3)) | |
res0: (Int, Traversable[Int]) = (1,WrappedArray(1, 2, 3)) | |
// Use implicit type constraints when we want to enrich an existing type while | |
// preserving that type in the type system | |
scala> :paste | |
// Entering paste mode (ctrl-D to finish) | |
trait ExtendedOps[F[_]] { | |
def first[A](c: F[A]): (A, F[A]) | |
} | |
object ExtendedOps { | |
implicit object ArrayOps extends ExtendedOps[Array] { | |
def first[A](c: Array[A]) = (c.head, c.tail) | |
} | |
// functional extension method | |
def first[A, F[_]](c: F[A])(implicit ev: ExtendedOps[F]) = ev.first(c) | |
} | |
import ExtendedOps._ | |
// Exiting paste mode, now interpreting. | |
warning: there were 2 feature warning(s); re-run with -feature for details | |
defined trait ExtendedOps | |
defined module ExtendedOps | |
import ExtendedOps._ | |
scala> first(Array(1,2,3)) | |
res2: (Int, Array[Int]) = (1,Array(2, 3)) | |
scala> :paste | |
// Entering paste mode (ctrl-D to finish) | |
// object-oriented extension method - pimp an existing type Array[A] | |
implicit class ArrayAugs[A](val x: Array[A]) extends AnyVal { | |
def first(implicit ev: ExtendedOps[Array]) = ev.first(x) | |
} | |
// Exiting paste mode, now interpreting. | |
defined class ArrayAugs | |
scala> Array(1,2,3).first | |
res0: (Int, Array[Int]) = (1,Array(2, 3)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment