0

in haskellのドキュメントを読んでいるとSDL、一部の関数が必然的にその入力を変更することがわかりました。たとえば、blitSurface入力としてデスティネーション サーフェスがありますが、関数内で更新されます。さて、問題を一般化すると、関数がある場合、関数内でf :: a -> IO a変更すると構成が壊れaますか? どうf :: IO a -> IO aですか?どうa -> IO ()ですか?そしてどうIO a -> IO ()ですか?

blitSurfaceが実際には外部関数であり、フレームごとに新しいサーフェスを作成するのはあまり効率的ではないことを考えると、これらの関数を避けるのは困難です。そのような関数は、より大きなスケールで問題を引き起こしますか? たとえば、fModifySurface :: Surface -> IO ()破壊的な更新を行う which を例として使用すると、次のようになります。

main = do
    w <- ... -- The window surface
    -- Do something here
    s <- someFuncGetSurface -- We get a surface here
    fModifySurface s -- Destructively update s
    blitSurface ...... -- Ignore the actual API, but destructively updates w

上記のコードに予期しないセマンティクスはありますか? もしそうなら、入力を変更する外部関数を利用する最良の方法は何ですか?

4

1 に答える 1

5

私はそれを観察しf a bflip f b aベータ版に相当する用語です。一方、IOこれらの簡単なバージョン、つまりf <$> a <*> bflip f <$> b <*> aは確かにベータ版と同等ではありません。また、 「Tackling the Awkward Squad」の等価性を使用しても、さらに多くのIOアクションが等価になりますが、これら 2 つの用語は等価ではありません。

大まかに言えば、これが意味することは、純粋項の動作について何かを証明すれば、純粋な計算がより大きなプログラムの一部として使用されている場合でも、その証明を再利用できるということです。一方、IO用語に関するローカルな証明をより大きな にIO基づくプログラムに関する証明に一様に持ち上げる対応する方法はありません。そうする場合は、一緒に使用する予定の特定のアクションに関するいくつかのグローバルプロパティを呼び出す必要があります。IO

これは、純粋な世界からできるだけ多くの計算を取り出しIOて純粋な世界に持ち込むという一般的なアドバイスの背後にある推進力です。実際、純粋な関数型プログラミング、つまり命令型プログラムを最初に行う主な動機の 1 つです。うまく構成しないでください。

ただし、この説明は、FFI やIO、入力の 1 つによって参照される値を更新するアクションを持つ関数に固有のものではありません。blitSurfaceこの点で、基本的に私たちが投げ入れる「罪のビン」のどれよりも悪くも良くもありませんIO。命令型プログラムは、純粋なプログラムと同じ意味で構成的ではありません。

于 2015-10-06T01:57:46.480 に答える