Skip to content

Instantly share code, notes, and snippets.

@milessabin
Last active April 16, 2018 02:39
Show Gist options
  • 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
implicitly[Foo].t+13
^
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
@soc
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?

@milessabin
Copy link
Author

Be my guest.

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