Skip to content

Instantly share code, notes, and snippets.

@cab
Created June 3, 2016 16:56
Show Gist options
  • Save cab/67f8ec3d07d7ed7255ddab6bcc3380f0 to your computer and use it in GitHub Desktop.
Save cab/67f8ec3d07d7ed7255ddab6bcc3380f0 to your computer and use it in GitHub Desktop.
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.reflect.runtime.universe._
import annotation.implicitNotFound
import concurrent.Future
import concurrent.ExecutionContext.Implicits.global
sealed trait Existence
trait Exists extends Existence
trait NotExists extends Existence
trait IsTypeClassExists[TypeClass, Answer]
object IsTypeClassExists {
private val evidence: IsTypeClassExists[Any, Any] =
new Object with IsTypeClassExists[Any, Any]
implicit def typeClassExistsEvidence[TypeClass, Answer](implicit a: TypeClass) =
evidence.asInstanceOf[IsTypeClassExists[TypeClass, Exists]]
implicit def typeClassNotExistsEvidence[TypeClass, Answer] =
evidence.asInstanceOf[IsTypeClassExists[TypeClass, NotExists]]
}
@implicitNotFound("Argument does not satisfy constraints: Not ${T}")
trait Not[T]
object Not {
private val evidence: Not[Any] = new Object with Not[Any]
implicit def notEvidence[T, Answer](implicit a: IsTypeClassExists[T, Answer], ne: Answer =:= NotExists) =
evidence.asInstanceOf[Not[T]]
}
def add[T](key: String, value: T)(implicit tt: TypeTag[T], nn: Not[T <:< Future[_]]): Map[String, Any] = {
Map(key -> value)
}
// Exiting paste mode, now interpreting.
import scala.reflect.runtime.universe._
import annotation.implicitNotFound
import concurrent.Future
import concurrent.ExecutionContext.Implicits.global
defined trait Existence
defined trait Exists
defined trait NotExists
defined trait IsTypeClassExists
defined object IsTypeClassExists
defined trait Not
defined object Not
add: [T](key: String, value: T)(implicit tt: reflect.runtime.universe.TypeTag[T], implicit nn: Not[<:<[T,scala.concurrent.Future[_]]])Map[String,Any]
scala> add("key", Future("f"))
<console>:43: error: Argument does not satisfy constraints: Not <:<[scala.concurrent.Future[String],scala.concurrent.Future[_]]
add("key", Future("f"))
^
scala> add("key", "f")
res13: Map[String,Any] = Map(key -> f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment