假设我有以下课程:
public class FixExpr {
Expr<FixExpr> in;
}
现在我想介绍一个泛型参数,抽象使用Expr:
public class Fix<F> {
F<Fix<F>> in;
}
但Eclipse并不喜欢这样:
F型不是通用的;它不能用参数<Fix <F >>进行参数化
这是可能的还是我忽略了导致这个特定实例破坏的东西?
一些背景信息:在Haskell中,这是编写泛型函数的常用方法;我正在尝试将其移植到Java . 上例中的类型参数F具有类型* - > 而不是通常的类型 . 在Haskell中它看起来像这样:
newtype Fix f = In { out :: f (Fix f) }
5 回答
我认为你想要做的就是Java泛型不支持 . 更简单的情况
也不使用javac编译 .
由于Java在编译时不知道
T
是什么,因此无法保证T<String>
完全有意义 . 例如,如果您创建了Foo<BufferedImage>
,则bar
将具有签名这是荒谬的 . 由于没有机制强制您仅使用泛型
T
实例化Foo
,因此它拒绝编译 .也许你可以尝试Scala,它是一种在JVM上运行的函数式语言,支持更高级的泛型 .
[ EDIT by Rahul G ]
以下是您的特定示例粗略转换为Scala的方式:
为了传递一个类型参数,类型定义必须声明它接受一个(它必须是通用的) . 显然,您的
F
不是通用类型 .更新:线
声明一个类型
F
的变量,它接受一个类型参数,其值为Fix
,它本身接受一个类型参数,其值为F
.F
甚至没有在您的示例中定义 . 我想你可能想要这将为您提供一个类型为
Fix
的变量(您在示例中定义的类型),您将向其传递值为F
的类型参数 . 由于Fix
被定义为接受类型参数,因此这是有效的 .更新2:重新阅读您的 Headers ,现在我认为您可能正在尝试执行与"Towards Equal Rights for Higher-Kinded Types"(PDF警报)中提供的方法类似的操作 . 如果是这样,Java不支持,但您可以尝试使用Scala .
仍然有一些方法可以用Java编码高质量的泛型 . 请看higher-kinded-java project .
使用它作为库,您可以像这样修改代码:
您应该在
Expr
类中添加@GenerateTypeConstructor
注释此批注生成ExprTypeConstructor类 . 现在您可以像这样处理您的Expr修复:
看起来你可能想要这样的东西:
(请参阅Enum类,以及有关其泛型的问题 . )