Take the 2-minute tour ×

This problem arose in a module I'm writing, but I have made a minimal case that exhibits the same behaviour.

class Minimal[T](x : T) {
  def doSomething = x

object Sugar {
  type S[T] = { def doSomething : T }
  def apply[T, X <: S[T]] (x: X) = x.doSomething

object Error {
  val a = new Minimal(4)
  Sugar(a) // error: inferred [Nothing, Minimal[Int]] does not fit the bounds of apply
  Sugar[Int, Minimal[Int]](a) // works as expected

The problem is that the compiler manages to figure out the inner parameter for Minimal (Int), but then sets the other occurrence of T to Nothing, which obviously does not match apply. These are definitely the same T, as removing the first parameter makes the second complain that T is not defined.

Is there some ambiguity that means that the compiler cannot infer the first parameter, or is this a bug? Can I work around this gracefully?

Further information: This code is a simple example of an attempt at syntactic sugar. The original code tries to make |(a)| mean the modulus of a, where a is a vector. Clearly |(a)| is better than writing |[Float,Vector3[Float]](a)|, but unfortunately I can't use unary_| to make this easier.

The actual error:

inferred type arguments [Nothing,Minimal[Int]] do not conform to method apply's type parameter bounds [T,X <: Sugar.S[T]]

share|improve this question
add comment

2 Answers

up vote 8 down vote accepted

This isn't a Scala compiler bug, but it's certainly a limitation of Scala's type inference. The compiler wants to determine the bound on X, S[T], before solving for X, but the bound mentions the so far unconstrained type variable T which it therefore fixes at Nothing and proceeds from there. It doesn't revisit T once X has been fully resolved ... currently type inference always proceeds from left to right in this sort of case.

If your example accurately represents your real situation then there is a simple fix,

def apply[T](x : S[T]) = x.doSomething

Here T will be inferred such that Minimal conforms to S[T] directly rather than via an intermediary bounded type variable.


Joshua's solution also avoids the problem of inferring type T, but in a completely different way.

def apply[T, X <% S[T]](x : X) = x.doSomething

desugars to,

def apply[T, X](x : X)(implicit conv : X => S[T]) = x.doSomething

The type variables T and X can now be solved for independently (because T is no longer mentioned in X's bound). This means that X is inferred as Minimal immediately, and T is solved for as a part of the implicit search for a value of type X => S[T] to satisfy the implicit argument conv. conforms in scala.Predef manufactures values of this form, and in context will guarantee that given an argument of type Minimal, T will be inferred as Int. You could view this as an instance of functional dependencies at work in Scala.

share|improve this answer
Yes, this solution works fine in my case. It is also cleaner than Joshua's solution (sorry Joshua!). Can you explain why Joshua's solution works, then? –  Dylan Apr 27 '12 at 18:37
Answer updated to give an explanation of why Joshua's solution also works. –  Miles Sabin Apr 27 '12 at 20:05
add comment

There's some weirdness with bounds on structural types, try using a view bound on S[T] instead.

def apply[T, X <% S[T]] (x: X) = x.doSomething works fine.

share|improve this answer
Great, this works, but surely there should be no difference between the approaches? Taking a view in this case is just casting to a superclass, isn't it? Does this mean that this fix is just a workaround for a bug in the compiler? –  Dylan Apr 27 '12 at 1:22
Ah, now I see, S is not a superclass - it is just a view (in a sense). So a view bound is more appropriate, despite not being required in most cases. –  Dylan Apr 27 '12 at 18:09
add comment

Your Answer


