それが適切な質問であるかどうかはわかりませんが、ここにあります。
Haskellのdo表記はかなりよく知っています。そして、Scalaの「理解力」は実際にはHaskellの表記法とほとんど同じであることに気付きました。デザイナーがこの名前を選んだのはなぜですか? 「for」と「yield」という言葉は、たとえばJavaのforループとRubyのyieldに慣れているプログラマーを混乱させる可能性があります。
しかし、私はモナドの構成がこれらのものとあまり共通点がないと思います。この構文糖をそのような言葉で名付ける特別な理由はありますか?それとも、その言語ですでに多くのキーワードが使用されているために、比較的無料であるこれらのキーワードを使用しなければならなかったからでしょうか。
ここで少し誤った二分法を作成していると思います。
Haskellには、モナド内包表記が言語に組み込まれています。その理由の1つは、命令型I/Oにモナドを使用することです。したがって、Haskellの設計者は、中括弧、セミコロン、さらにはreturn
さえも備えた、一般的なCスタイル言語のコードブロックのように見えるようにすることを決定しました。割り当ては少しCではないように見えますが、割り当ての左矢印は典型的な命令型疑似コードです。
つまり、Haskellのモナド内包表記は、いくつかの一般的なC /疑似コードのような言語では、命令型の逐次的な副次的なコードブロックのように見えるように設計されています。これは、前述のreturn
関数の名前がAPIデザインに浸透します。この関数の名前は、do
表記以外で使用する場合、あまり意味がありません。
C#には、モナド内包表記が言語に組み込まれています。その理由の1つは、データセットのクエリにモナドを使用することです。したがって、C#のデザイナーは、SQLまたはXQueryのように見えるようにすることを決定し、FROM
、SELECT
、WHERE
、GROUPBY
、ORDERBY
など。順序は少しSQLではないように見えますが(FROM
の前はSELECT
)、実際にはXQueryで使用されるものと同じです。
つまり、C#のモナド内包表記はSQLクエリのように見えるように設計されています。これは、API設計にも浸透します。変換関数のSelect
(map
の代わりに)、SelectMany
(flatMap
の代わりに)、Where
(select
/filter
)など。これらの操作の名前は、クエリ内包の外で使用する場合はあまり意味がなく、実際には混乱を招きやすい(Select
は通常map
と呼ばれるものですが、通常select
はWhere
)と呼ばれます。
Scalaには、モナド内包表記が言語に組み込まれています。その理由の1つは、コレクション操作にモナドを使用することです。したがって、Scalaの設計者は、それを一般的なCスタイル言語のfor
ループのように見えるようにすることを決定しました。割り当ては少し非Cに見えますが、割り当ての矢印は、典型的な命令型の疑似コードです。
したがって、Scalaのモナド内包表記は、いくつかの一般的なC /疑似コードのような言語では命令型のfor
ループのように見えるように設計されています。これはそれらの重要な使用例だからです。
C#とScalaの両方の場合、内包構文は実際には2つのモナド演算join
を実行するよりもmoreおよび/またはlessを実行できます。 bind
(またはmap
およびflatMap
)。 Scalaでは、for
のないyield
内包表記はforeach
に変換されます。つまり、必須の副作用の反復であり、実際にはモナドとはほとんど関係ありません。 yield
はガード(yield foo if bar
)を持つことができ、これはwithFilter
への呼び出しへの呼び出し、つまり要素のフィルタリングに変換されます。 C#はWhere
でも同じことができます。 C#では、集計(group by
)と並べ替え(order by
)も実行できます。
それらは実際にはモナド内包表記と任意のコレクションとモナドに一般化されたリスト内包表記の一般化と融合のどちらかです。 Haskellにも両方ありますが、それらはdifferentのものであり、C#とScalaでは融合されています。
Haskellには多くの歴史があり、多くのコンセプトを開拓してきました。先駆者の典型であるように、彼らの後を追う人々は、より良く、より短く、より安全なルートを発見します。おそらく、Haskellがイノベーションではなく後知恵で設計されていた場合、より多くのコレクションで機能するように一般化されたリスト内包表記があり、モナド内包表記と一般化されたコレクション内包表記を融合させたでしょう。 Haskellには、たとえばArrow Comprehensionsを追加する提案されたバリアントや拡張機能があることを知っています。
「for」と「yield」という言葉は、たとえばJavaのforループとRubyのyieldに慣れているプログラマーを混乱させる可能性があります。
最初は意図的なものです。 for
ループのように見えるのは想定です。
二つ目は残念です。 Word yield
には2つの意味があります(実際には関連していますが、明らかに関連していません)。 1つは、同時実行、コルーチン、ファイバー、スレッド、およびRubyのyield
キーワードとFibre#yield
メソッドで使用される意味であり、コードの一部が実行の制御を別の部分に与えることを意味しますコードの。もう1つは、結果を生成する計算の意味です。これは、Pythonジェネレータ、C#ジェネレータ、および興味深いことにRubyのEnumerator::Yielder#yield
メソッドで使用されている意味であり、yield
Scala for
内包表記のキーワード。
Scala=デザイナーがその特定の表現を選択した理由はあまりわかりませんが、F#では、ローカルの「表記法」に相当するものを「計算式」と呼びます。そのWordを選択した理由具体的な技術的な理由ではなく、PRとマーケティングの1つです。
Haskellは、学者、ロケット科学者、その他の奇妙な言語のための言語であると苦労して得た評判があり、この概念を永続させるものの1つは、オープンに型理論から派生した用語を使用することに対するコミュニティの主張です。これは、マーケティングの一種でもあります。ある種の人々(関数型プログラミングのヒップスター)にとって魅力的であり、他の人々(たとえば、企業の採用者)に対して不快感を与える意識的な選択と言えます。
F#については、「表記法」や「モナド」ではなく「計算式」や「計算式ビルダー」を使用して、言語を習得する可能性のある人々(関数型プログラミングのバックグラウンドはありません)。
Scalaの場合も同様だと思います。これを「内包表記」と呼ぶことで、モナドについて何も知らないかもしれないが、RubyやPythonなどの言語のリスト内包表記に精通している)人々にその機能を売りたいと考えています。