Haskell 包含“runST”的函数的类型签名`

Haskell 包含“runST”的函数的类型签名`,haskell,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写什么签名 (背景)

我可以这样写:

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
写什么签名

(背景)


这是我正在编写的真实代码的简化示例。首先,我有一个在中工作的函数(例如ST或IO)。它对向量进行了大量的操作。我正在为此创建一个纯包装器,但需要传入初始可变向量,它将生成一个纯向量。与前面提到的更一般的函数不同,纯包装器只在ST.中工作。

您要查找的类型签名是:

{-# 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)

(对于所有s.ST s a)
确保
x
无法决定
s
将是什么,因此
x
必须对所有
s
起作用,因此它不能从
ST
计算中泄漏
STRef
或类似内容

您要查找的类型签名是:

{-# 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)

(对于所有s.ST s a)
确保
x
无法决定
s
将是什么,因此
x
必须对所有
s
起作用,因此它不能从
ST
计算中泄漏
STRef
或类似内容

如果没有签名,编译器就看不到
h
的参数的含义。如果您添加签名
h::(对于所有s.ST s a)->a
runST
希望选择
m
作为
ST s
,其中
s
再次由
runST
选择,则它将编译。在后一种情况下,
x
必须已经具有类型
ST s…
,但它来自外部,因此其他人已经选择了
s
——runST的参数不够通用。一种选择是让
x::forall s。ST s…
但这是一个多类型,GHC不会推断这些。如果没有签名,编译器无法理解
h
的参数的含义。如果您添加签名
h::(对于所有s.ST s a)->a
runST
希望选择
m
作为
ST s
,其中
s
再次由
runST
选择,则它将编译。在后一种情况下,
x
必须已经具有类型
ST s…
,但它来自外部,因此其他人已经选择了
s
——runST的参数不够通用。一种选择是让
x::forall s。ST s…
但这是一个多类型,GHC并没有推断出这些。感谢当我为我的实际问题尝试这样做时,它没有成功,所以我要么塞满了什么东西,要么我的问题实际上与此不同。这可能与以下事实有关:
s
是由
MonadRef
中的一个类型族提供的。但我必须看到实际的代码来演示您的问题,才能看到它是什么。感谢我为我的实际问题尝试了类似这样的方法,但没有成功,因此我要么塞满了一些东西,要么我的问题实际上与此不同。可能与
s
是由类型族提供的这一事实有关在
MonadRef
中。但我必须看到实际的代码来演示您的问题,看看它是什么。