我想要类似的东西
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。
另外,请参阅这个问题。问题是,这些都是非常丑陋的解决方案。所以我提出了第三种选择,即通过运行“应该”作为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
使用unsafePerformIO
可变向量时的含义)感兴趣。