7

私は何かが欲しい

f :: [forall m. (Mutable v) (PrimState m) r -> m ()] -> v r -> v r -- illegal signature
f gs x = runST $ do
  y <- thaw x
  foldM_ (\_ g -> g y) undefined gs -- you get the idea
  unsafeFreeze y

私は基本的に、この質問で Vitus がコメントしたのと同じ立場にいます。

[I]多相関数を構造内に保持したい場合は、特殊なデータ型 (例: newtype I = I (forall a. a -> a)) または ImpredicativeTypes が必要です。

また、この質問を参照してください。問題は、これらは両方とも本当に醜い解決策だということです。そこで私は 3 番目の代替案を思いつきました。それは、代わりにST計算を実行する「べき」ものを実行することで、ポリモーフィズムを完全に回避するIOことです。したがって、次のようfになります。

f :: [(Mutable v) RealWorld r -> IO ()] -> v r -> v r
f gs x = unsafePerformIO $ do
  y <- thaw x
  foldM_ (\_ g -> g y) undefined gs -- you get the idea
  unsafeFreeze y

unsafe IO「安全な」ルートと比較して、このルートに行くのは少し汚いと感じますSTが、私の代替手段がラッパーまたは非予測型である場合...どうやら、私は一人ではありません。

ここで使用してはいけない理由はありunsafePerformIOますか?この場合、本当に安全ではないのでしょうか? パフォーマンスに関する考慮事項やその他の注意事項はありますか?

- - - - - - - 編集 - - - - - - - -

以下の回答は、この問題を完全に回避する方法を示しています。これは素晴らしいことです。しかし、教育目的で元の質問(変更可能なベクトルを使用する場合のrunSTvsの含意)にはまだ興味があります。unsafePerformIO

4

1 に答える 1

5

まだ問題文を完全に理解しているとは言えませんが、次のファイルは GHC 7.6.2 でエラーなくコンパイルされます。最初の例と同じ本体を持っています (特に、まったく呼び出しませんunsafePerformIO)。主な違いは、forallがすべての型コンストラクタの外に移動されていることです。

{-# LANGUAGE RankNTypes #-}
import Control.Monad
import Control.Monad.Primitive (PrimState)
import Control.Monad.ST
import Data.Vector.Generic hiding (foldM_)

f :: Vector v r => (forall m. [Mutable v (PrimState m) r -> m ()]) -> v r -> v r
f gs x = runST $ do
  y <- thaw x
  foldM_ (\_ g -> g y) undefined gs
  unsafeFreeze y

STそれでは、対のIO質問に取り組みましょう。呼び出されて呼び出さunsafePerformIOれない理由unusablePerformIOは、コンパイラによってチェックできない証明の負担が伴うためです。実行しているものunsafePerformIOは、参照透過的であるかのように動作する必要があります。STアクションには、 で実行されたときに透過的に動作するという (コンパイラでチェックされた) 証明が付属しているため、これは、 を使用する場合よりも、型チェックインするコードでrunSTを使用しても危険がないことを意味します。unsafePerformIOSTrunST

BUT : ソフトウェア エンジニアリングの観点からは危険です。証明がコンパイラでチェックされなくなったため、将来のリファクタリングで安全に使用できる条件に違反しやすくなりますunsafePerformIO。したがって、それを回避できる場合 (ここにあるようです)、そうするように努力する必要があります。(さらに、「これ以上危険はない」は「危険がない」という意味ではありません。unsafeFreezeあなたが行っている呼び出しには、あなたが満たさなければならない独自の証明負担があります。しかし、STコードが正しい。)

于 2013-11-15T03:41:43.570 に答える