为包含`runST`的函数键入签名

时间:2016-12-21 14:44:59

标签: haskell

我可以这样写:

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。

1 个答案:

答案 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计算。