我可以这样写:
import Control.Monad.ST (runST)
x :: (Monad m) => m a
x = undefined
f = runST x
如果没有f
的签名,这将很乐意编译。
所以我尝试了类似的东西:
g :: (Monad m) => m a -> m a
g = undefined
h x = runST (g x)
然而,如果没有签名,这不会编译。我并不介意,因为runST
是排名2类型,但我无法确定要为h
撰写的签名。
(背景)
这是真实代码I的简化示例。首先,我有一个在MonadRef中工作的功能(例如ST或IO)。它对矢量进行了很多操作。我为此创建了一个纯粹的包装器,但是需要传入初始的可变向量,它将生成一个纯矢量。与更常见的首次提到的功能不同,纯包装器仅适用于ST。
答案 0 :(得分:4)
您正在寻找的类型签名是:
{-# LANGUAGE RankNTypes #-}
module Test where
import Control.Monad.ST
g :: (Monad m) => m a -> m a
g = undefined
h :: (forall s. ST s a) -> a
h x = runST (g x)
(forall s. ST s a)
确保x
无法确定s
将会是什么,因此x
必须适用于所有s
,因此无法泄露STRef
{1}}或类似的ST
计算。