6

unsafePerformIOとその同類の使用を禁止するという部門全体の方針にすることについて、いくつかの話がありました。個人的には、自分が使いたいと思ったら、自分のアプローチを考え直す必要があるといつも思っていたので、気にしません。

この制限は合理的に聞こえますか?主にFFI用に含まれていることをどこかで読んだことを覚えているようですが、今どこで読んだか思い出せません。

編集:わかりました、それは私のせいです。合理的に必要な場所、つまり制限されません。FFI。ポリシーのポイントは、怠惰とコードの臭いを思いとどまらせることです。

4

5 に答える 5

13

多くのコアライブラリは、たとえばメモリ割り当てをカスタマイズするために、内部でByteString使用するようなものです。unsafePerformIO

このようなライブラリを使用する場合、ライブラリの作成者がエクスポートされたAPIの参照透過性を証明し、ユーザーに必要な前提条件が文書化されていることを信頼できます。全面的な禁止ではなく、部門は、社内で同様の保証を行うためのポリシーとレビュープロセスを確立する必要があります。

于 2010-10-08T19:22:25.117 に答える
12

さて、の有効な使用法がありunsafePerformIOます。それは単に装飾的であるため、またはあなたの美徳をテストする誘惑としてそこにあるのではありません。ただし、これらの使用法には、日常のコードに意味のある副作用を追加することは含まれていません。さまざまな程度の疑いを持って、正当化される可能のある使用例をいくつか示します。

  • 内部的には不純であるが、外部から観察できる副作用がない関数をラップします。これはモナドと同じ基本的な考え方ですが、STここでは不純物が「漏れない」ことを示す責任がプログラマーにある点が異なります。

  • 何らかの制限された方法で故意に不純な機能を偽装する。たとえば、書き込み専用の不純物は、生成される出力を観察する方法がないため、「内部から」の完全な純度と同じように見えます。これは、モナドに必要な一貫性と明確に定義された順序を明示的に望まない、ある種のロギングまたはデバッグに役立ちます。IOこの例はDebug.Trace.trace、私が時々呼ぶ、unsafePerformPrintfDebuggingです。

  • 純粋な計算の内省、純粋な結果の生成。古典的な例は、明確な選択演算子のようなものです。これは、2つの同等の純粋関数を並行して実行して、より迅速に回答を得ることができます。

  • データの初期化時に非決定性を導入するなど、内部的に観察できない参照透過性の破壊。各不純関数が1回だけ評価される限り、同じ引数で呼び出された同じ偽純粋関数が異なる実行で異なる結果をもたらす場合でも、参照透過性はプログラムの1回の実行中に効果的に保持されます。

上記のすべてについて注意すべき重要なことは、結果として生じる不純物が注意深く制御され、範囲が制限されていることです。万能モナドよりも副作用を制御するよりきめ細かいシステムを考えると、これらはすべて、前述のモナドIOの制御された可変状態のように、半純度のビットをスライスするための明白な候補になります。ST


スクリプト後:不必要な使用に対する強硬な姿勢unsafePerformIOが検討されている場合は、禁止事項を拡張して、その動作を観察できる機能を含めることを強くお勧めします。unsafeInterleaveIOあなたが私に尋ねれば、それは少なくともunsafePerformIO私が上にリストしたいくつかの例と同じくらい大ざっぱです。

于 2010-10-08T19:33:44.087 に答える
7

unsafePerformIOは、IOモナドのrunSTです。それは時々不可欠です。ただし、runSTとは異なり、コンパイラは参照透過性が保持されていることを確認できません。

したがって、それを使用する場合、プログラマーは使用が安全である理由を説明する責任があります。それは禁止されるべきではなく、証拠を伴うべきです。

于 2010-10-08T21:04:49.787 に答える
4

unsafePerformIO「アプリケーション」コードの非合法化は優れたアイデアです。私の意見では、通常のコードには言い訳はなくunsafePerformIO、私の経験では必要ありません。それは実際には言語の一部ではないので、それを使用する場合、Haskellで実際にプログラミングすることはもうありません。それが何を意味するのかをどうやって知るのですか?

一方、unsafePerformIOFFIバインディングでの使用は、自分が何をしているのかを知っている場合は合理的です。

于 2010-10-13T22:24:32.893 に答える
3

unsafePerformIOを非合法化することは、コードをIOモナドに効果的にロックするため、ひどい考えです。たとえば、ACライブラリバインディングはほとんどの場合IOモナドにありますが、unsafePerformIOを使用すると、その上に高レベルの純粋関数型ライブラリを構築できます。 。

間違いなく、unsafePerformIOは、パーソナルコンピュータの非常にステートフルなモデルとhaskellの純粋なステートレスモデルの間の妥協点を反映しています。関数呼び出しでさえ、引数をスタックにプッシュしたり、レジスターをいじったりする必要があるため、コンピューターの観点からはステートフルですが、使用法は、これらの操作が実際に機能的に構成されるという知識に基づいています。

于 2010-10-09T00:01:40.640 に答える