monad的一般情况是否在java 6中可以表达?

时间:2012-11-25 15:06:57

标签: java generics haskell monads higher-kinded-types

在Java 6中是否可以表达monad的一般情况?注意“一般情况”这个词 - monad的一般情况可能是不可表达的,尽管Monad的许多特殊情况(即许多特定的monad)都是可表达的。

这里的问题是(缺少)Higher-kinded generics in Java;但是,我看到样本Haskell代码实际上是使用像https://stackoverflow.com/a/877036/1123502这样的方法移植到Java(即public class Fix<F extends Fix<F>>)。

当然,非类型安全的实现(比如使用Object和downcast)并不感兴趣。

更新:有两种常见的monad定义:join-fmap和bind-return。虽然它们(数学上)是等价的,但它们可能不等同于一个定义在Java中可表达,而其他定义则不然(但在我看来,非等价是不可能的)。所以我的问题涉及两个定义。

底线:是否有人克服了所有障碍并在Java 6中编写了“一般案例”monad?或者,或者,请指出论文或完整的博客文章,或彻底解释为什么不可能。

1 个答案:

答案 0 :(得分:5)

不是没有肮脏的铸造技巧。正如您已经注意到的,Java不支持类型级别多态(a.k.a。“Scala land中的”更高级别的类型“)。

这是一种方式:假设您想要实现一个仿函数。您想写Functor<F<A>>,其中F例如是List MaybeBase<X,Y>,但不起作用。但是对于更高级的东西,你可以拥有一个“基类”XList必须是真实班级的“见证人”,例如YFunctor<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) { ... } }

Base<List.Witness,B>

当然要支付的价格是您获得List<B>而不是{{1}}。如果你留在那个更高级别的领域,这可能没问题,当然你可以为了方便而拥有转换功能,但它仍然不是很好。

对于实施,请参阅我不太认真的项目highJ。请注意,我正在开发一个完全重写且更方便的版本,更接近上面的示例。

对于严肃的代码,请考虑在Scala中编写这样的东西(或使用Scalaz)。