Scala inferred type arguments - Type bounds inferring to 'Nothing'

generics, scala, type-bounds, type-inference

Solution

In order to encode the relationship between the two type parameters, you can use something like

case class Query[U, T](schema: U)(implicit ev: U <:< Schema[T]) { ... }

See §4.3 and §4.4 of the Scala Language Spec for more info.

Problem

I'm attempting to write a simple query monad and am having trouble getting my generic type annotations correct. My first attempt went as follows (vastly simplified for conciseness) ``` case class Person( val name: String ) abstract class Schema[T] object People extends Schema[Person] case class Query[U <: Schema[T], T]( schema: U ) { <---- Type signature def results: Seq[T] = ... def where( f: U => Operation ) = ... } class TypeText extends Application { val query = Query( People ) <---- Type inference fails } ``` The compiler didn't like this, as it couldn't infer the type of 'T'. error: inferred type arguments [People.type,Nothing] do not conform to method apply's type parameter bounds [U <: Schema[T],T] While experimenting I found that using view bounds instead works as expected ``` case class Query[U <% Schema[T], T]( schema: U ) { ``` (Note the use of view bound "<%" instead of type bound "<:") However in my limited understanding of the type system, since I'm expecting an actual subclass (and not just convertibility) of Schema[T], I would assume type bound "<:" is the correct bounds to be using here? If this is the case, what am I missing - how do I give the compiler enough hints to infer T correctly when using type bounds instead of view bounds?

Original source