私は何かが欲しい
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
ますか?この場合、本当に安全ではないのでしょうか? パフォーマンスに関する考慮事項やその他の注意事項はありますか?
- - - - - - - 編集 - - - - - - - -
以下の回答は、この問題を完全に回避する方法を示しています。これは素晴らしいことです。しかし、教育目的で元の質問(変更可能なベクトルを使用する場合のrunST
vsの含意)にはまだ興味があります。unsafePerformIO