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
中。但我必须看到实际的代码来演示您的问题,看看它是什么。