Skip to content

Instantly share code, notes, and snippets.

@frankleonrose
Created October 28, 2014 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save frankleonrose/542d430a48e726b189db to your computer and use it in GitHub Desktop.
Save frankleonrose/542d430a48e726b189db to your computer and use it in GitHub Desktop.
IsNotFuture - Scala
trait IsNotFuture[F] {
type T
def apply(f: F): T
}
object IsNotFuture {
def apply[F](implicit isf: IsNotFuture[F]) = isf
implicit def mkFuture[A] = new IsNotFuture[Future[A]] {
type T = Int // Doesn't matter
def apply(f: Future[A]): T = 0
}
implicit def mk[A] = new IsNotFuture[A] {
type T = A
def apply(f: A): A = f
}
}
// Alternatively, you could synchronize all futures...
// implicit def mkFuture[A] = new IsNotFuture[Future[A]] {
// type T = A
// def apply(f: Future[A]): A = Await.result(f, 1 seconds)
// }
// Here's my use case - don't want fn to leak a Future that keeps using the session after cleanup
def inSession[T](fn: (Session) => T)(implicit isNotFuture: IsNotFuture[T]): isNotFuture.T = {
isNotFuture(db withSession fn)
}
// Compiler fails as desired
inSession { session => Future(1) }
@wheaties
Copy link

You don't need the dependent type. See here: https://gist.github.com/wheaties/a49e2f5c2e1e3c3286f3

Otherwise, good use of implicit divergence.

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