Skip to content

Instantly share code, notes, and snippets.

Last active April 16, 2018 02:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save milessabin/8833a1dbf7e8245b30f8 to your computer and use it in GitHub Desktop.
Save milessabin/8833a1dbf7e8245b30f8 to your computer and use it in GitHub Desktop.
Now in shapeless 2.1.0-SNAPSHOT: "shapeless.the" an enhanced alternative to "Predef.implicitly".
// Used as a term `the[T]` yields the unique implicit value of type `T` in the current
// implicit scope, if any. It is a compile time error if there is no such value. Its
// primary advantage over `Predef.implicitly` is that it will preserve any refinement that
// the implicit definition has, resulting in more precisely typed, and hence often more
// useful, values,
scala> trait Foo { type T ; val t: T }
defined trait Foo
scala> implicit val intFoo: Foo { type T = Int } = new Foo { type T = Int ; val t = 23 }
intFoo: Foo{type T = Int} = $anon$1@6067b682
scala> implicitly[Foo].t // implicitly loses precision
res0: Foo#T = 23
scala> implicitly[Foo].t+13
<console>:13: error: type mismatch;
found : Int(13)
required: String
scala> the[Foo].t // the retains it
res1: Int = 23
scala> the[Foo].t+13
res2: Int = 36
// Unlike `implicitly`, `the` can also be used in type position, thanks to a trick
// due to Denys Shabalin (@den_sh) and Eugene Burmako (@xeno_by). Here we use a
// combination of `selectDynamic` and backticks to embed a type in a path which
// appears to the compiler as stable,
scala> val i: implicitly[Foo].T = 23 // syntax error
<console>:1: error: ';' expected but '.' found.
val i: implicitly[Foo].T = 23
scala> val i: the.`Foo`.T = 23 // OK
i: Int = 23
Copy link

soc commented Aug 17, 2014

Would it make sense to write a patch against Scala and try to get this improvement included in implicitly?

Copy link

Be my guest.

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