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
使用泛型T
s 实例化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)
为了传递一个类型参数,类型定义必须声明它接受一个(它必须是通用的).显然,您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.
归档时间: |
|
查看次数: |
4951 次 |
最近记录: |