Skip to content

Instantly share code, notes, and snippets.

@johnynek
Last active January 22, 2016 21:46
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save johnynek/edc66bb5d1e8c90430dd to your computer and use it in GitHub Desktop.
A zero cost, type-safe equals function in scala
import scala.language.experimental.macros
import scala.reflect.macros.Context
/**
* you can try this in the REPL even
*/
object SafeEq {
/**
* eqv(1, "foo") won't compile
*/
def eqv[A, B](a: A, b: B): Boolean = macro eqvMacro[A, B]
def eqvMacro[A, B](c: Context)(
a: c.Expr[A],
b: c.Expr[B])(implicit A: c.WeakTypeTag[A], B: c.WeakTypeTag[B]): c.Expr[Boolean] = {
import c.universe._
if (A == B) c.Expr[Boolean](q"""$a == $b""")
else c.abort(c.enclosingPosition, s"types: $A and $B do not match")
}
}
@rklaehn
Copy link

rklaehn commented Nov 15, 2015

Interesting. What's the advantage over the approach used by the === operator in spire? Here is the macro I use: https://github.com/non/spire/blob/master/macros/src/main/scala/spire/macros/Syntax.scala#L46

I think the performance characteristics should be the same, so I guess it is a matter of taste if you want the =:= in the type signature or not.

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