5

そのような関数を想像してください:

bar :: Foo -> A -> B -> C -> IO ()

その関数は、 aおよびその他の値IOを使用していくつかのことを実行します。値は に渡す必要があり、次Fooの方法で取得できます。FoobarIO

foo :: X -> IO Foo

現在、ABCおよびXはすべて単純な純粋な値です。私はむしろそのようなbar機能が欲しいです:

bar :: X -> A -> B -> C -> IO ()

そして、値を使用して関数Fooで生成されます。私がそれを行う場合:barX

let f = bar myX

f :: A -> B -> C -> IO (). その関数を何回か呼んでもX部分適用で値は変わらないのですが、IO効果なので毎回発生してしまいます。生成されたクロージャに対して、値が一度生成されるように、ある種のキャッシュを実行するネイティブ組み込みの ghc の方法はありますか? Fooそれはすべてボクシングに関連していると思いますが、IORefのパラメーターを展開するdirty を使用せずにそれを行う方法がわかりませんでしbarた。これは醜いです。

4

1 に答える 1

12

あなたが文字通り求めていることは、Haskellの大きな「いいえ」である参照透過性を壊します。それで、質問unsafeLaunchMissilesが残ります.あなたが文字通り求めているが非常に落胆していることを(時々、あなたが幸運で最適化がそれを壊さないなら)行うような方法をあなたに示すべきですか、それともきれいな方法を示すべきですか種類が少し変わる?後者を試してみましょう。

bar代わりに次のタイプを作成する場合:

bar :: X -> IO (A -> B -> C -> IO ())

do次に、ブロックで使用できます。

f <- bar myX

barまたは、 を再定義するポイントを見逃していると思われる場合はX、代わりに最初の型を保持barして実行します

f <- bar =<< foo myX
于 2014-09-04T10:14:43.397 に答える