35

モナドは、IOを処理するためのhaskellソリューションとして説明されています。純粋な関数型言語でIOを処理する他の方法があるかどうか疑問に思いました。

4

7 に答える 7

37

純粋な関数型言語でのI/Oのモナドに代わるものは何ですか?

私は文献の2つの選択肢を知っています:

  • 1つはいわゆる線形型システムです。線形型の値は1回だけ使用する必要があるという考え方です。無視することはできず、2回使用することもできません。このアイデアを念頭に置いて、世界の状態に抽象型(たとえばWorld)を与え、それを線形にします。線形タイプに星印を付ける場合、いくつかのI/O操作のタイプは次のとおりです。

    getChar :: World* -> (Char, World*)
    putChar :: Char -> World* -> World*
    

    等々。コンパイラーは、ワールドをコピーしないように調整します。次に、ワールドを適切に更新するコードをコンパイルするように調整します。これは、コピーが1つしかないため安全です。

    Cleanという言語での一意性の入力は、線形性に基づいています。

    このシステムにはいくつかの利点があります。特に、モナドが行うイベントの全体的な順序付けは強制されません。またIO、Haskellで見られる「罪のビン」を回避する傾向があります。この場合、すべての効果的な計算がモナドに投げ込まれ、IO全順序が必要かどうかに関係なく、すべてが完全に順序付けられます。

  • 私が知っているもう1つのシステムは、モナドとクリーンよりも前のものであり、対話型プログラムは(おそらく無限の)一連の要求から(おそらく無限の)一連の応答までの関数であるという考えに基づいています。「ダイアログ」と呼ばれるこのシステムは、プログラミングするのにまったく地獄でした。誰もそれを見逃すことはなく、特にそれをお勧めすることは何もありませんでした。その欠点は、WadlerとPeytonJonesによるモナディックI/ O(命令型関数型プログラミングを紹介した論文にうまく列挙されています。この論文はまた、エール・ハスケル・グループによって導入されたが短命であった継続に基づくI/Oシステムについても言及している。

于 2010-01-28T22:55:59.310 に答える
8

線形タイプの他に、エフェクトシステムもあります。

于 2010-02-07T07:30:33.747 に答える
5

Cleanでは一意性の型付けが使用されます

于 2010-01-28T21:31:53.923 に答える
5

「純粋」とは「参照透過性」を意味する場合、つまり、適用された関数がその評価結果と自由に交換可能である場合(したがって、同じ引数で関数を呼び出すと毎回同じ結果が得られる)、ステートフルIOの概念定義上、ほとんど除外されています。

私が知っている2つの大まかな戦略があります:

  • 関数にIOを実行させますが、まったく同じ引数で2回呼び出されないようにしてください。これは、関数を自明に「参照透過性」にすることで問題を回避します。

  • プログラム全体を単一の純粋関数として扱い、「すべての入力を受け取った」を引数として取り、「すべての出力を生成した」を返します。どちらも、対話性を可能にする何らかの形式の遅延ストリームで表されます。

両方のアプローチを実装するにはさまざまな方法があり、ある程度の重複もあります。たとえば、2番目のケースでは、I / Oストリームで動作する関数が、ストリームの同じ部分で2回呼び出される可能性はほとんどありません。それをどのように見るかがより理にかなっているのは、その言語がどのようなサポートを提供しているかによって異なります。

HaskellではIO、コードを介してシーケンシャル状態を自動的にスレッド化するタイプのモナドであり(機能的に純粋なStateモナドと同様)、概念的には、そうでなければ不純な関数への各呼び出しは、外界の暗黙の「状態」の異なる値を取得します"。

私が知っている他の一般的なアプローチは、同様の目的で線形型のようなものを使用します。コピーまたは複製できない値を使用して、不純な関数が同じ引数を2回取得しないようにすることで、「外界の状態」の古い値を保持して再利用することができなくなります。

于 2010-01-28T21:46:22.767 に答える
5

関数型IOに興味がある場合は、PeytonJonesとWadlerによる命令型関数型プログラミングを読む必要があります。彼らが議論する他のアプローチは次のとおりです。

  • 応答と要求の怠惰な流れである対話

type Dialogue = [Response] -> [Request]

main :: Dialogue

  • 継続-各IO操作は引数として継続を取ります

  • 線形型-型システムは、外部状態をコピーまたは破棄できないように制限します。つまり、同じ状態で関数を2回呼び出すことはできません。

于 2010-01-28T22:53:04.830 に答える
3

関数型リアクティブプログラミングは、これを処理するもう1つの方法です。

于 2014-05-29T18:10:57.163 に答える
1

純粋な関数型言語でIOを処理する他の方法があるかどうか疑問に思いました。

すでにここにある他の答えに追加するだけです:

  • この論文のタイトルはそれをすべて言います:-)
  • また見ることができます:

Rebelsky SA(1992)I/Oツリーとインタラクティブな怠惰な関数型プログラミング。In:Bruynooghe M.、Wirsing M.(eds)プログラミング言語の実装と論理プログラミング。PLILP 1992.コンピュータサイエンスのレクチャーノート、vol631。Springer、Berlin、Heidelberg

  • Haskellが若い頃、Lennart Augustssonは、I/Oのメカニズムとしてシステムトークンを使用することについて次のように書いています。

L.オーガストソン。システムトークンを使用した機能I/O。PMGメモ72、コンピュータサイエンス学部、チャルマース工科大学、S-412 96ヨーテボリ、1989年。

オンラインコピーはまだ見つけていませんが、差し迫った必要はありません。それ以外の場合は、Chalmersの図書館に連絡することをお勧めします。

于 2020-06-04T23:18:43.213 に答える