use*_*502 5 java generics monads haskell higher-kinded-types
在Java 6中是否可以表达monad的一般情况?注意单词"一般情况" - monad的一般情况可能是不可表达的,尽管monad(即许多特定monad)的许多特定情况是可表达的.
这里的问题是(缺乏)Java中更高级的泛型 ; 但是,我看到样本Haskell代码实际上是使用像/sf/answers/61392551/(即public class Fix<F extends Fix<F>>)这样的方法移植到Java .
当然,非类型安全的实现(如使用Object和downcast)并不有趣.
更新:有两个常见的monad定义:join-fmap和bind-return.虽然它们(数学上)是等价的,但它们可能不等同于一个定义在Java中可表达,而其他定义则不然(但在我看来,非等价是不可能的).所以我的问题涉及两个定义.
底线:是否有人克服了所有障碍并在Java 6中编写了"一般案例"monad?或者,或者,请指出一篇论文或一篇全面的博客文章,或彻底解释为什么不可能.
不是没有肮脏的铸造技巧.正如您已经注意到的,Java不支持类型级别多态(在Scala域中也称为"更高级的类型").
这是一种方式:假设您想要实现一个仿函数.你想写Functor<F<A>>,在哪里F,例如,List或Maybe,但不起作用.但是你可以拥有一个"基类" Base<X,Y>来获得更高级的东西.X必须是你真正的班级的"见证人" List.Y是通常的通用参数.现在你的函子变成了Functor<Base<F,A>>,但是所有想要与之一起使用的类需要实现Base<X,Y>:
class List<A> implements Base<List.Witness,A> {
public class Witness{}
...
}
public interface Functor<F> {
public <A, B> Base<F, B> map(F1<A, B> fn, Base<F, A> nestedA);
}
public class ListFunctor implements Functor<List.Witness> {
public <A, B> Base<List.Witness, B> map(F1<A, B> fn, Base<List.Witness, A> nestedA) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
当然要支付的价格是你得到的Base<List.Witness,B>,而不是a List<B>.如果你留在那个更高级别的领域,这可能没问题,当然你可以为了方便而拥有转换功能,但它仍然不是很好.
对于实现,请参阅我不太认真的项目highJ.请注意,我正在开发一个完全重写且更方便的版本,更接近上面的示例.
对于严肃的代码,请考虑在Scala中编写这样的东西(或使用Scalaz).