2012-11-25 8 views
5

Java 6で表現可能なモナドの一般的なケースですか? 「一般的なケース」という語に注意してください。—モナドの一般的なケースは表現可能ではない可能性がありますが、モナドの多くの特定のケース(すなわち多くの特定のモナド)が表現可能です。Java 6で表現可能なモナドの一般的なケースですか?

ここでの問題は(欠けている)Higher-kinded generics in Javaです。しかし、サンプルのHaskellコードが実際にhttps://stackoverflow.com/a/877036/1123502(つまり、public class Fix<F extends Fix<F>>)のようなアプローチを使用してJavaに移植されていることがわかりました。

もちろん、型のない実装(Objectやダウンキャストなど)は興味深いものではありません。

更新: 2つの共通のモナド定義があります:join-fmapとbind-returnです。それらは(数学的に)同等ですが、ある定義がJavaで表現可能であるという意味では同等ではないかもしれませんが、他の定義は表現できません(ただし、非等価性はありそうもないようです)。だから私の質問は両方の定義に関係している。

結論:誰もがすべての障害を克服し、Java 6で "一般的なケース"のモナドを書きましたか?あるいは、論文や徹底的なブログ記事を指摘したり、それがなぜ不可能であるかを完全に説明したりしてください。

+2

[* Monads in Java *](http://logicaltypes.blogspot.com/2011/09/monads-in-java.html)も参照してください。 – trashgod

+2

@trashgodその実装では、 'bind'の戻り値の型は' M 'ではなく 'Monad 'です。これはJavaでは不可能です。その結果、Monadから継承するListクラスがある場合、そのリストで 'bind'を呼び出すと別のリストが生成されるという保証はないので、' MonadicList strings = myMonadicList.bind( ...) 'キャストなし。 ... – sepp2k

+1

...その記事で与えられている抽象クラスは、モナドコンセプトの完全な正しい実装ではありません(ただし、Javaで手に入れることができるように近いかもしれません)。 – sepp2k

答えて

5

汚れていないキャストトリックはありません。既に触れたように、Javaは型レベルの多型(Scala土地では「上位の類型」)をサポートしていません。

ここには1つの方法があります:ファンクタを実装したいとします。 Functor<F<A>>と書いたければ、Fとなります。 a 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) { 
     ... 
    } 
} 

もちろん支払う価格はあなたが戻ってBase<List.Witness,B>、ないList<B>を得るということです。あなたがその高級なドメインにとどまるなら、これはうまくいくかもしれません。もちろん、便宜のために変換機能を持つことはできますが、それでもそれほど良いものではありません。

実装については、それほど深刻ではないプロジェクトhighJを参照してください。上記の例の近くで、私は完全に書き直され、やや便利なバージョンに取り組んでいることに注意してください。

深刻なコードの場合は、代わりにScalaにそのようなものを書くことを検討してください(Scalazを使用する)。

関連する問題