Higher-kinded generics in Java

I think what you're trying to do is simply not supported by Java generics. The simpler case of

public class Foo<T> {
    public T<String> bar() { return null; }
}

also does not compile using javac.

Since Java does not know at compile-time what T is, it can't guarantee that T<String> is at all meaningful. For example if you created a Foo<BufferedImage>, bar would have the signature

public BufferedImage<String> bar()

which is nonsensical. Since there is no mechanism to force you to only instantiate Foos with generic Ts, it refuses to compile.


In order to pass a type parameter, the type definition has to declare that it accepts one (it has to be generic). Apparently, your F is not a generic type.

UPDATE: The line

F<Fix<F>> in;

declares a variable of type F which accepts a type parameter, the value of which is Fix, which itself accepts a type parameter, the value of which is F. F isn't even defined in your example. I think you may want

Fix<F> in;

That will give you a variable of type Fix (the type you did define in your example) to which you are passing a type parameter with value F. Since Fix is defined to accept a type parameter, this works.

UPDATE 2: Reread your title, and now I think you might be trying to do something similar to the approach presented in "Towards Equal Rights for Higher-Kinded Types" (PDF alert). If so, Java doesn't support that, but you might try Scala.


Maybe you can try Scala, which is a functional language running on JVM, that supports higher-kinded generics.


[ EDIT by Rahul G ]

Here's how your particular example roughly translates to Scala:

trait Expr[+A]

trait FixExpr {
  val in: Expr[FixExpr]
}

trait Fix[F[_]] {
  val in: F[Fix[F]]
}