Collect instances via LiftAll - scala

I'm trying to describe the types which a case class contains.
import shapeless._
import shapeless.ops.hlist.LiftAll
trait Desc[T] {
def description: String
}
case class Foo(f: Int)
object Foo {
implicit val description: Desc[Foo] = new Desc[Foo] { val description = "foo" }
}
case class SomeCaseClass(f: Foo)
val gen = Generic[SomeCaseClass]
val lifted = implicitly[LiftAll[Desc, gen.Repr]].instances.toList
Gives me
could not find implicit value for parameter toTraversableAux: shapeless.ops.hlist.ToTraversable.Aux[shapeless.ops.hlist.LiftAll[Playground.this.Desc,Playground.this.gen.Repr]#Out,List,Lub]
not enough arguments for method toList: (implicit toTraversableAux: shapeless.ops.hlist.ToTraversable.Aux[shapeless.ops.hlist.LiftAll[Playground.this.Desc,Playground.this.gen.Repr]#Out,List,Lub])toTraversableAux.Out.
Unspecified value parameter toTraversableAux.
Scastie here: https://scastie.scala-lang.org/bXu71pMQQzCqrrsahVBkWA

When you summon an implicit instance with implicitly[LiftAll[Desc, gen.Repr]] then the dependent type Out of LiftAll is lost, so the compiler doesn't know which type exactly instances will return.
To work around this problem most typeclasses in Shapeless define an apply method in their companion object which does retain all dependent type information. It's the reason that you can use gen.Repr in a meaningful way after calling val gen = Generic[SomeCaseClass]. For some reason however LiftAll.apply was not implemented in this way. So that leaves you the option of implementing your own implicitly, or since you're using Shapeless anyway, use its the which is supposed to be a better implicitly.
scala> def impl[T <: AnyRef](implicit ev: T): ev.type = ev
impl: [T <: AnyRef](implicit ev: T)ev.type
scala> impl[LiftAll[Desc, gen.Repr]].instances.toList
res1: List[Desc[Foo]] = List(Foo$$anon$1#40b3708a)
scala> the[LiftAll[Desc, gen.Repr]].instances.toList
res2: List[Desc[Foo]] = List(Foo$$anon$1#40b3708a)
You can see the difference here in the inferred types that the REPL displays:
scala> impl[LiftAll[Desc, gen.Repr]]
res3: LiftAll.Aux[Desc,Foo :: HNil,Desc[Foo] :: HNil] = shapeless.ops.hlist$LiftAll$$anon$206#384d060c
scala> implicitly[LiftAll[Desc, gen.Repr]]
res4: LiftAll[Desc,gen.Repr] = shapeless.ops.hlist$LiftAll$$anon$206#30787774

Related

Using `implicit def`

Given a made-up F type-class:
scala> trait F[A] {}
defined trait F
and this definition, which uses a context bound to require that the input A has a type-class instance of F:
scala> def f[A : F](x: A) = ???
f: [A](x: A)(implicit evidence$1: F[A])Nothing
I defined a Person and type-class instance:
scala> case class Person(name: String)
defined class Person
scala> implicit val person: F[Person] = new F[Person] {}
person: F[Person] = $anon$1#262b2c86
And the following compiles:
scala> f(Person("foo"))
scala.NotImplementedError: an implementation is missing
But, there's no String implementation, so it fails.
scala> f("foobar")
<console>:17: error: could not find implicit value for evidence parameter of type F[String]
f("foobar")
^
I then defined an F[String] using:
scala> implicit def fInstance(x: String) = new F[String] {}
fInstance: (x: String)F[String]
But, I can't run:
scala> f("foobar")
<console>:18: error: could not find implicit value for evidence parameter of type F[String]
f("foobar")
^
since I do not have an implicit F[String], but rather a String => F[String].
What's the proper way to use such an implicit def to meet the F[String] constraint, i.e. call the f function successfully with a type of String?
I got it to work via:
scala> implicit val x: F[String] = implicitly[String => F[String]].apply("foobar")
x: F[String] = $anon$1#7b7fdc8
scala> f("foobar")
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
at .f(<console>:12)
... 33 elided
But I'm not sure if it's the right/clean way to do it.
You defined an implicit conversion. If you want to use a def to provide typeclass instances you just write the same as you'd write an implicit val but replace val with def.
implicit def fInstance = new F[String] {}
Normally you only use a def if you need type parameters, like here.
implicit def fInstance[A] = new F[List[A]] {}
Or
implicit def fInstance[A](implicit ev: F[A]) = new F[List[A]] {}
Your fInstance defines an implicit conversion, i.e. a way to turn a String into F[String]. For generating a typeclass instance, a method accepting implicit parameters can be used:
implicit def fInstance(implicit x: String) = new F[String] {}
it is typically used in FP libraries to derive one typeclass from another:
implicit def optionMonoid[A](implicit S: Semigroup[A]): Monoid[Option[A]] = ???
// or, which is the same
// implicit def optionMonoid[A: Semigroup]: Monoid[Option[A]] = ???
The idea is that F[String] can operate on any String in general, not being dependent on actual arguments provided into function. Of course, you can always provide instances explicitly:
f("foobar")(new F[String] { })
As a follow-up, the important part of typeclasses is that you can define them ad-hoc, i.e. not having access to definitions of F and String at all, and you are forced to scope implicits in Scala and import them, so it's totally ok.
Here is a simpler version of your definition (and you can remove implicit from fInstance):
implicit val singleFInstance: F[String] = fInstance("") // or fInstance("foobar"), etc.
Whether this is the right thing to do, very much depends on what F and f are supposed to mean.
But generally speaking: if F is really a type-class, fInstance(string) gives different results depending on the string (not just different instances, but different behavior), and f's signature is correct, then this is wrong and you should accept that calling f("foobar") isn't meaningful.

A => Class[A] using ClassTag?

Looking at ClassTag#runtimeClass, it has a return type of Class[_], i.e. a Class with, as I understand, a wildcard parameter.
I tried to implement a method: A => ClassTag[A]:
import scala.reflect._
scala> def f[A](x: A)(implicit ev: ClassTag[A]) = ev.runtimeClass
f: [A](x: A)(implicit ev: scala.reflect.ClassTag[A])Class[_]
But, the output of the def's definition is, as the docs show, Class[_].
Is it possible to change f such that its return type is Class[A]? If not, then why is it not possible?
Unless you change the signature of f, your only option is to cast the Class[_] to a Class[A].
There is literally only one method in the entire Scala standard library that returns a Class[A], and that is classOf. f[A] cannot be re-written to use classOf[A] since it is a special compiler method and is incompatible with generic type parameters that may not be classes. You would simply get an error:
scala> def f[A: ClassTag](x: A) = classOf[A]
<console>:10: error: class type required but A found
def f[A: ClassTag](x: A) = classOf[A]
^
The best you can get without casting is using x.getClass, but that will return a Class[_ <: A] (no ClassTag needed).
scala> def f[A](x: A): Class[_ <: A] = x.getClass
f: [A](x: A)Class[_ <: A]
scala> f(1)
res8: Class[_ <: Int] = class java.lang.Integer
scala> f(List(1, 2, 3))
res9: Class[_ <: List[Int]] = class scala.collection.immutable.$colon$colon
You might ask, why _ <: A?
The answer to that question is also the reason why your definition of f doesn't really make sense. If A is an Int, it makes sense to be able to return a Class[A] because Int is a class. But what if A is a List[Int]? List[Int] is not a class, it's a type. The class is List, but A != List, therefore we cannot return a Class[A] consistently. We can, however, have an upper-bound of A on the type parameter of Class.

Scala Manifested with Parameterized Types

Is it possible to get the type parameters of a manifest type included in the class object.
I might not be describing that correctly, so what I mean is, given this type.
Resultset[Band[Coldplay]]
I want a manfiest that represents the full type, so that it should be possible to get a class instance that has the type
Class[Resultset[Band[Coldplay]]]
All I can get is
Class[Resultset[_]]
You could build a manifest into a class:
case class Manifesting[A](value: A)(implicit val mf: Manifest[A]) { }
scala> Manifesting(5).mf.erasurescala> Manifesting(5).mf.erasure
res1: Class[_] = int
Or you can build all the manifests into a method:
def nested[A, B[A]](x: B[A])(implicit ma: Manifest[A], mb: Manifest[B[A]]) =
(ma.erasure, mb.erasure)
scala> nested(List("fish"))
res2: (Class[_$1], Class[_$1]) forSome { type _$1; type _$1 } =
(class java.lang.String,class scala.collection.immutable.List)
Or, in Scala 2.10 you can use TypeTag:
def nest2[A: scala.reflect.runtime.universe.TypeTag](x: A) =
implicitly[scala.reflect.runtime.universe.TypeTag[A]]
scala> nest2(Right(List("salmon","herring")))
res3: reflect.runtime.universe.TypeTag[scala.util.Right[Nothing,List[String]]] =
TypeTag[scala.util.Right[Nothing,List[String]]]

Scala Macros: "cannot create TypeTag from a type T having unresolved type parameters"

I'm playing around with Scalas new macros and found this gist from akshaal. As it seams I did not quite get it.
Given the following trait (the fieldsMacro is more or less the same as in akshaal example)
case class Field[I <: AnyRef](name: String, get: I => Any)
type Fields[I <: AnyRef] = List[Field[I]]
trait FieldAccess {
import FieldMacors._
import Field._
import language.experimental.macros
def fields[T <: AnyRef]: Fields[T] = macro fieldsMacro[T]
def field[T <: AnyRef](name: String): Fields[T] = fields[T].headOption <-- does not work!
^
}
object FieldMacors {
import language.experimental.macros
import Field._
def fields[T <: AnyRef]: Fields[T] = macro fieldsMacro[T]
/**
* Get a list of fiels
*/
def fieldsMacro[T <: AnyRef: c.TypeTag](c: Context): c.Expr[Fields[T]] = {
import c.universe._
val instanceT = c.typeOf[T]
val fields = instanceT.members.filter(member => member.isTerm && !member.isMethod)
// transform an iterable of expr in a expr of list.
def foldIntoListExpr[T: c.TypeTag](exprs: Iterable[c.Expr[T]]): c.Expr[List[T]] =
exprs.foldLeft(reify { Nil: List[T] }) {
(accumExpr, expr) =>
reify { expr.splice :: accumExpr.splice }
}
val fieldAccessores = for (field <- fields) yield {
val name = field.name.toString.trim // Why is there a space at the end of field name?!
val nameExpr = c literal name
// Construct expression (x : $I) => x.$name
val getFunArgTree = ValDef(Modifiers(), newTermName("x"), TypeTree(instanceT), EmptyTree)
val getFunBodyTree = Select(Ident(newTermName("x")), newTermName(name))
val getFunExpr = c.Expr[T => Any](Function(List(getFunArgTree), getFunBodyTree))
reify {
Field[T](name = nameExpr.splice, get = getFunExpr.splice)
}
}
foldIntoListExpr(fieldAccessores)
}
}
the compiler complains about
'Cannot create TypeTag from a type T having unresolved type parameters'
How do I manage to get the T to the macro or must I implement another macro that uses the fieldsMacro
T: TypeTag context bound for a type parameter T means that you require type arguments provided in place of this parameter to be concrete (i.e. not contain references to untagged type parameters or abstract type members). Otherwise an error occurs.
Examples:
scala> val ru = scala.reflect.runtime.universe
ru # 6d657803: scala.reflect.api.JavaUniverse = scala.reflect.runtime.JavaUniverse#6d657803
scala> def foo[T: ru.TypeTag] = implicitly[ru.TypeTag[T]]
foo: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]
scala> foo[Int]
res0 # 7eeb8007: reflect.runtime.universe.TypeTag[Int] = TypeTag[Int]
scala> foo[List[Int]]
res1 # 7d53ccbe: reflect.runtime.universe.TypeTag[List[Int]] = TypeTag[scala.List[Int]]
scala> def bar[T] = foo[T] // T is not a concrete type here, hence the error
<console>:26: error: No TypeTag available for T
def bar[T] = foo[T]
^
scala> def bar[T] = foo[List[T]] // T being not concrete renders
// the entire compound type not concrete
<console>:26: error: No TypeTag available for List[T]
def bar[T] = foo[List[T]]
^
scala> def bar[T: TypeTag] = foo[T] // to the contrast T is concrete here
// because it's bound by a concrete tag bound
bar: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]
scala> bar[Int]
res2 # 7eeb8007: reflect.runtime.universe.TypeTag[Int] = TypeTag[Int]
scala> def bar[T: TypeTag] = foo[List[T]]
bar: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[List[T]]
scala> bar[Int]
res3 # 1a108c98: reflect.runtime.universe.TypeTag[List[Int]] = TypeTag[scala.List[Int]]
scala> bar[List[Int]]
res4 # 76d5989c: reflect.runtime.universe.TypeTag[List[List[Int]]] = TypeTag[scala.List[scala.List[Int]]]
Having a notion of concrete types to be enforcible at compile-time is useful. Having concrete type tags on by default is useful as well as described in https://issues.scala-lang.org/browse/SI-5884.
However as you've seen yourself, concrete type tags in macros can be a source of confusion, because typically macros should work both for concrete and non-concrete types. Therefore one should always use c.AbsTypeTag instead. Due to this reason we no longer allow c.TypeTag context bounds in 2.10.0-M7: https://github.com/scala/scala/commit/788478d3ab.
Edit. In 2.10.0-RC1 some AbsTypeTag has been renamed to WeakTypeTag. Everything else about type tags remains the same.

What is the Scala identifier "implicitly"?

I have seen a function named implicitly used in Scala examples. What is it, and how is it used?
Example here:
scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
| implicit def stringImpl = new Foo[String] {
| def apply(list : List[String]) = println("String")
| }
| implicit def intImpl = new Foo[Int] {
| def apply(list : List[Int]) = println("Int")
| }
| } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined trait Foo
defined module Foo
foo: [A](x: List[A])(implicit evidence$1: Foo[A])Unit
scala> foo(1)
<console>:8: error: type mismatch;
found : Int(1)
required: List[?]
foo(1)
^
scala> foo(List(1,2,3))
Int
scala> foo(List("a","b","c"))
String
scala> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
Foo[Double]
foo(List(1.0))
^
Note that we have to write implicitly[Foo[A]].apply(x) since the compiler thinks that implicitly[Foo[A]](x) means that we call implicitly with parameters.
Also see How to investigate objects/types/etc. from Scala REPL? and Where does Scala look for implicits?
implicitly is avaliable in Scala 2.8 and is defined in Predef as:
def implicitly[T](implicit e: T): T = e
It is commonly used to check if an implicit value of type T is available and return it if such is the case.
Simple example from retronym's presentation:
scala> implicit val a = "test" // define an implicit value of type String
a: java.lang.String = test
scala> val b = implicitly[String] // search for an implicit value of type String and assign it to b
b: String = test
scala> val c = implicitly[Int] // search for an implicit value of type Int and assign it to c
<console>:6: error: could not find implicit value for parameter e: Int
val c = implicitly[Int]
^
Here are a few reasons to use the delightfully simple method implicitly.
To understand/troubleshoot Implicit Views
An Implicit View can be triggered when the prefix of a selection (consider for example, the.prefix.selection(args) does not contain a member selection that is applicable to args (even after trying to convert args with Implicit Views). In this case, the compiler looks for implicit members, locally defined in the current or enclosing scopes, inherited, or imported, that are either Functions from the type of that the.prefix to a type with selection defined, or equivalent implicit methods.
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
Implicit Views can also be triggered when an expression does not conform to the Expected Type, as below:
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
Here the compiler looks for this function:
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
Accessing an Implicit Parameter Introduced by a Context Bound
Implicit parameters are arguably a more important feature of Scala than Implicit Views. They support the type class pattern. The standard library uses this in a few places -- see scala.Ordering and how it is used in SeqLike#sorted. Implicit Parameters are also used to pass Array manifests, and CanBuildFrom instances.
Scala 2.8 allows a shorthand syntax for implicit parameters, called Context Bounds. Briefly, a method with a type parameter A that requires an implicit parameter of type M[A]:
def foo[A](implicit ma: M[A])
can be rewritten as:
def foo[A: M]
But what's the point of passing the implicit parameter but not naming it? How can this be useful when implementing the method foo?
Often, the implicit parameter need not be referred to directly, it will be tunneled through as an implicit argument to another method that is called. If it is needed, you can still retain the terse method signature with the Context Bound, and call implicitly to materialize the value:
def foo[A: M] = {
val ma = implicitly[M[A]]
}
Passing a subset of implicit parameters explicitly
Suppose you are calling a method that pretty prints a person, using a type class based approach:
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
What if we want to change the way that the name is output? We can explicitly call PersonShow, explicitly pass an alternative Show[String], but we want the compiler to pass the Show[Int].
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)
Starting Scala 3 implicitly has been replaced with improved summon which has the advantage of being able to return a more precise type than asked for
The summon method corresponds to implicitly in Scala 2. It is
precisely the same as the the method in Shapeless. The difference
between summon (or the) and implicitly is that summon can return a
more precise type than the type that was asked for.
For example given the following type
trait F[In]:
type Out
def f(v: Int): Out
given F[Int] with
type Out = String
def f(v: Int): String = v.toString
implicitly method would summon a term with erased type member Out
scala> implicitly[F[Int]]
val res5: F[Int] = given_F_Int$#7d0e5fbb
scala> implicitly[res5.Out =:= String]
1 |implicitly[res5.Out =:= String]
| ^
| Cannot prove that res5.Out =:= String.
scala> val x: res5.Out = ""
1 |val x: res5.Out = ""
| ^^
| Found: ("" : String)
| Required: res5.Out
In order to recover the type member we would have to refer to it explicitly which defeats the purpose of having the type member instead of type parameter
scala> implicitly[F[Int] { type Out = String }]
val res6: F[Int]{Out = String} = given_F_Int$#7d0e5fbb
scala> implicitly[res6.Out =:= String]
val res7: res6.Out =:= String = generalized constraint
However summon defined as
def summon[T](using inline x: T): x.type = x
does not suffer from this problem
scala> summon[F[Int]]
val res8: given_F_Int.type = given_F_Int$#7d0e5fbb
scala> summon[res8.Out =:= String]
val res9: String =:= String = generalized constraint
scala> val x: res8.Out = ""
val x: res8.Out = ""
where we see type member type Out = String did not get erased even though we only asked for F[Int] and not F[Int] { type Out = String }. This can prove particularly relevant when chaining dependently typed functions:
The type summoned by implicitly has no Out type member. For this
reason, we should avoid implicitly when working with dependently typed
functions.
A "teach you to fish" answer is to use the alphabetic member index currently available in the Scaladoc nightlies. The letters (and the #, for non-alphabetic names) at the top of the package / class pane are links to the index for member names beginning with that letter (across all classes). If you choose I, e.g., you'll find the implicitly entry with one occurrence, in Predef, which you can visit from the link there.