I have an abstract class TSData which has abstract type T, T is going to be implemented as a case class. So I defined it this way:
abstract case class A()
type T<:A
I wanted to create a concrete method in TSData which uses method from another library, but I get this error:
Error:(23, 53) Type info for type ‘TSData.this.T’ not available. Make sure it is a (nested) case class with [Double or Int or Boolean or Seq[Double]] members only.
As I understood from this error, my type T isn’t limited to have the members of only certain types mentioned above. Right? How can I make such constraints? Should I use Manifest here somehow?
Thanks, I understood that there is nothing I can do, I will have to define it in each concrete class. I just didn’t understand the words you used:
What does mean being in scope for a type? I understood the problem as that @implicitNotFound will not accept an abstract type, and it is put there by the reason cos a function has to do some tests on that type’s properties. I didn’t see this as a scope problem, can you explain?
I don’t know which library or classes we are talking about, so I’ll assume there is something like this somewhere:
@implicitNotFound("Type info for type ‘${A}’ not available. Make sure it is a (nested) case class with [Double or Int or Boolean or Seq[Double]] members only.")
trait Foo[A]
Then there is some method which requires an implicit Foo:
def foo[A](implicit foo: Foo[A]) = ???
This library probably has some implicit macros that generate an implicit Foo[X] for every X which is a case class with the right kind of members.
You have something like this:
abstract case class A()
trait Bar {
type T <: A
def bar() = println(foo[T])
}
This fails because that macro does not know whether or not the abstract type T conforms to its requirements. So at the point where you call foo[T]there is no implicit Foo[T] in scope. To fix that you have to make sure there is one in scope. Usually you do this by adding an implicit parameter to the method where you need that implicit ( def bar()(implicit fooT: Foo[T]) = println(foo[T]) ). Although in this case T is not a type parameter of method bar so you could also do this:
trait Bar {
type T <: A
implicit def fooT: Foo[T]
def bar() = println(foo[T])
}
// and then
class Baz extends Bar {
type T = MyCaseClass
implicit val fooT: Foo[MyCaseClass] = {
def fooT = ??? // shadow fooT, required to avoid implicitly finding itself
implicitly[Foo[MyCaseClass]]
}
}