Java中更高级的泛型

Mar*_*ijn 31 java generics polymorphism haskell higher-kinded-types

假设我有以下课程:

public class FixExpr {
  Expr<FixExpr> in;
}
Run Code Online (Sandbox Code Playgroud)

现在我想介绍一个泛型参数,抽象使用Expr:

public class Fix<F> {
  F<Fix<F>> in;
}
Run Code Online (Sandbox Code Playgroud)

但Eclipse并不喜欢这样:

F型不是通用的; 它不能用参数<Fix <F >>进行参数化

这是可能的还是我忽略了导致这个特定实例破坏的东西?

一些背景信息:在Haskell中,这是编写泛型函数的常用方法; 我正在尝试将其移植到Java.上例中的类型参数F具有类型* - >*而不是通常的类型*.在Haskell中它看起来像这样:

newtype Fix f = In { out :: f (Fix f) }
Run Code Online (Sandbox Code Playgroud)

Zar*_*nen 26

我认为你想要做的就是Java泛型不支持.更简单的情况

public class Foo<T> {
    public T<String> bar() { return null; }
}
Run Code Online (Sandbox Code Playgroud)

也不使用javac编译.

由于Java在编译时不知道什么T是,它不能保证T<String>完全有意义.例如,如果您创建了一个Foo<BufferedImage>,则bar会有签名

public BufferedImage<String> bar()
Run Code Online (Sandbox Code Playgroud)

这是荒谬的.由于没有强制您仅Foo使用泛型Ts 实例化s的机制,因此它拒绝编译.


Zel*_*luX 25

也许你可以尝试Scala,它是一种在JVM上运行的函数式语言,支持更高级的泛型.


[编辑Rahul G ]

以下是您的特定示例粗略转换为Scala的方式:

trait Expr[+A]

trait FixExpr {
  val in: Expr[FixExpr]
}

trait Fix[F[_]] {
  val in: F[Fix[F]]
}
Run Code Online (Sandbox Code Playgroud)


Han*_*Gay 5

为了传递一个类型参数,类型定义必须声明它接受一个(它必须是通用的).显然,您F不是通用类型.

更新:线

F<Fix<F>> in;
Run Code Online (Sandbox Code Playgroud)

声明一个类型的变量,F它接受一个类型参数,其值是Fix,它本身接受一个类型参数,其值是F.F在您的示例中甚至没有定义.我想你可能想要

Fix<F> in;
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个类型的变量Fix(您在示例中定义的类型),您将使用值传递一个类型参数F.由于Fix定义为接受类型参数,因此可行.

更新2:重新阅读你的头衔,现在我认为你可能会尝试做类似于"建立更高级别类型的平等权利"(PDF警报)中提出的方法.如果是这样,Java不支持,但您可以尝试使用Scala.