83

モナドが何であるかを理解するのを助けるために、誰かがjavaを使用して例を提供できますか?それらは可能ですか?

プレリリースのラムダ互換JDK8をここからダウンロードすると、Javaを使用してラムダ式を使用できますhttp://jdk8.java.net/lambda/

このJDKを使用したラムダの例を以下に示します。誰かが比較的単純なモナドを提供できますか?

public interface TransformService {
        int[] transform(List<Integer> inputs);
    }
    public static void main(String ars[]) {
        TransformService transformService = (inputs) -> {
            int[] ints = new int[inputs.size()];
            int i = 0;
            for (Integer element : inputs) {
                ints[i] = element;
            }
            return ints;
        };

        List<Integer> inputs = new ArrayList<Integer>(5) {{
            add(10);
            add(10);
        }};
        int[] results = transformService.transform(inputs);
    }
4

10 に答える 10

84

参考までに:

提案されたJDK8 Optionalクラスは、モナドの 3 つの法則を満たしています。ここにそれを示す要点があります。

モナドに必要なのは、 3 つの法則に従う2 つの関数を提供することだけです。

2 つの機能:

  1. 値をモナド コンテキストに配置する

    • Haskell's Maybe: return/Just
    • Scala のオプション:Some
    • Functional Java のオプション:Option.some
    • JDK8 のオプション:Optional.of
  2. モナドのコンテキストで関数を適用する

    • Haskell の Maybe: >>=(aka bind)
    • Scala のオプション:flatMap
    • Functional Java のオプション:flatMap
    • JDK8 のオプション:flatMap

3 つの法則の Java デモンストレーションについては、上記の要旨を参照してください。

注: 理解すべき重要なことの 1 つは、モナド コンテキストに適用する関数のシグネチャです。生の値の型を取り、モナド型を返します。

言い換えると、 のインスタンスがある場合、Optional<Integer>そのメソッドに渡すことができる関数にflatMapは署名があります(Integer) -> Optional<U>。は、 である必要のUない値の型IntegerですString

Optional<Integer> maybeInteger = Optional.of(1);

// Function that takes Integer and returns Optional<Integer>
Optional<Integer> maybePlusOne = maybeInteger.flatMap(n -> Optional.of(n + 1));

// Function that takes Integer and returns Optional<String>
Optional<String> maybeString = maybePlusOne.flatMap(n -> Optional.of(n.toString));

このようにコーディングしたり、このように考えたりするのに、モナドインターフェースは必要ありません。Scala では、Monad Interface にコーディングしません (Scalaz ライブラリを使用している場合を除きます...)。JDK8 は、Java 関係者がこのスタイルのチェーン化されたモナド計算も使用できるようにするようです。

これが役に立てば幸いです!

更新:これについてのブログはこちら.

于 2013-11-12T14:55:25.423 に答える
58

Java 8 にはラムダがあります。モナドはまったく別の話です。それらを関数型プログラミングで説明するのは十分に困難です (Haskell と Scala の主題に関するチュートリアルが多数あることからも明らかです)。

モナドは、静的に型付けされた関数型言語の典型的な機能です。オブジェクト指向で説明すると、Monadインターフェイスを想像できます。Monad実装するクラスは、実装を実装Monadする際に「モナドの法則」として知られているものに従う場合、「モナド」と呼ばれます。次に、この言語は、クラスのインスタンスの操作を興味深いものにする構文糖衣を提供します。Monad

Java ではモナドIterableとは何の関係もありませんが、Java コンパイラが特別に扱う型 ( foreachJava 5 に付属する構文) の例として、次のことを考慮してください。

Iterable<Something> things = getThings(..);
for (Something s: things) {  /* do something with s */ }

したがって、古いスタイルのループでIterableIteratorメソッド (および会社) を使用することもできましたが、Java では、この構文糖衣を特別なケースとして認めています。hasNextfor

したがって、実装Iterableし、法則Iteratorに従わなければならないクラス (例:次の要素がない場合は返さなければならない) が構文で役立つように、対応する表記法 (Haskell で呼び出されるように)で役立ついくつかのモナドクラス が存在します。 ) または Scala の表記。IteratorhasNextfalseforeachdofor

そう -

  1. モナドクラスの良い例は何ですか?
  2. それらを処理するための構文糖衣はどのようになりますか?

Java 8 ではわかりません。ラムダ表記については知っていますが、他の特別な構文糖衣については知らないので、別の言語で例を挙げなければなりません。

多くの場合、モナドはコンテナークラスとして機能します (リストはその例です)。Javajava.util.Listにはすでに明らかにモナドではないものがありますが、Scala のものは次のとおりです。

val nums = List(1, 2, 3, 4)
val strs = List("hello", "hola")
val result = for { // Iterate both lists, return a resulting list that contains 
                   // pairs of (Int, String) s.t the string size is same as the num.
  n <- nums        
  s <- strs if n == s.length 
} yield (n, s)
// result will be List((4, "hola")) 
// A list of exactly one element, the pair (4, "hola")

これは(大まかに)次の構文糖衣です。

val nums = List(1, 2, 3, 4)
val strs = List("hello", "hola")
val results = 
nums.flatMap( n =>                 
  strs.filter(s => s.size == n).   // same as the 'if'
       map(s => (n, s))            // Same as the 'yield'
)
// flatMap takes a lambda as an argument, as do filter and map
// 

これは、モナドを利用してリスト内包表記を提供する Scala の機能を示しています。

したがって、ListScala の a はモナドです。これは、Scala のモナドの法則に従っているためです。この法則は、すべてのモナドの実装が適合するflatMap,mapおよびfilterメソッドを持たなければならないことを規定しています (この法則に興味がある場合は、「Monads are Elephants」ブログ エントリに最適な説明があります。これまでに発見されました)。そして、ご覧のとおり、ラムダ (および HoF) は絶対に必要ですが、この種のものを実用的な方法で使用するには十分ではありません。

コンテナっぽいもの以外にも、便利なモナドがたくさんあります。それらにはあらゆる種類のアプリケーションがあります。私のお気に入りはOption、Scala のモナド (Haskell のモナド) です。これは、 null 安全性Maybeをもたらすラッパー型です: モナドの Scala API ページには、非常に単純な使用例があります: http://www.scala-lang. org/api/current/scala/Option.html Haskell では、非モナド Haskell コードの実行順序が不確定であるという事実を回避する方法として、モナドは IO を表すのに役立ちます。Option

ラムダを持つことは、関数型プログラミングの世界への最初の小さな一歩です。モナドには、モナド規約と、使用可能なモナド型の十分な大きさのセットの両方が必要です。また、モナドを楽しく便利に扱うための構文糖衣も必要です。

Scala はほぼ間違いなく Java に最も近い言語であり、(モナディックな) 関数型プログラミングも可能です。(まだ) 興味がある場合は、Scala の Monad チュートリアルをご覧ください: http://james-iry.blogspot.jp/2007/09/ monads-are-elephants-part-1.html

大雑把にグーグルで調べると、Java でこれを行う試みが少なくとも 1 回あることがわかります: https://github.com/RichardWarburton/Monads-in-Java -

悲しいことに、Java でモナドを説明することは (ラムダ式であっても)、本格的なオブジェクト指向プログラミングを ANSI C (C++ や Java ではなく) で説明するのと同じくらい難しいです。

于 2012-11-19T14:15:56.563 に答える
5

モナドを理解する唯一の方法は、多数のコンビネータライブラリを作成し、結果として生じる重複に気づき、モナドによってこの重複を除外で​​きることを自分で発見することです。これを発見することで、誰もがモナドとは何かについて何らかの直感を構築します…しかし、この直感は、他の誰かに直接伝えることができるようなものではありません。誰もが、コンクリートからモナドに一般化するという同じ経験を経なければならないようです。コンビネータライブラリの例。でも

ここで私はモンダスを学ぶためのいくつかの資料を見つけました。

あなたにも役立つことを願っています。

codecommit

james-iry.blogspot

debasishg.blogspot

于 2012-11-19T13:20:42.620 に答える
2

このブログ投稿では、モナド型 (インターフェース) を Java で実装し、それを使用して Maybe モナドを実際のアプリケーションとして定義する方法の例を段階的に示します。

この投稿では、Java 言語には 1 つのモナドが組み込まれていることを説明し、モナドは多くのプログラマーが考えるよりも一般的であり、コーダーはしばしば不注意でモナドを再発明するという点を強調しています

于 2012-12-18T04:48:53.310 に答える