Haskell编译报错:无法匹配`a`与`STRef s Integer`类型
关于Haskell中runST与STRef的编译报错问题
编译runST (newSTRef 1)时会出现如下报错:
Couldn't match type
a' withSTRef s Integer'
Expected: ST s a
Actual: ST s (STRef s Integer)
但执行返回普通类型(如Integer)的代码runST ((newSTRef 1) >>= readSTRef)时,却能正常运行。以下是问题原因的解释:
这是由runST的类型约束决定的。runST的类型签名为runST :: (forall s. ST s a) -> a,它要求传入的ST计算最终返回的类型a不能包含被量化的状态参数s——也就是说a必须是与ST状态无关的纯类型。
newSTRef 1的类型是ST s (STRef s Integer),返回的STRef s Integer中包含了状态参数s,违反了runST的约束,因此编译器报错。- 而
(newSTRef 1) >>= readSTRef的类型是ST s Integer,最终返回的Integer是纯类型,不包含s,完全符合runST的要求,所以可以正常编译运行。
本质上,runST的设计目的是封装ST计算,只允许将纯值从ST上下文中提取到纯代码中,禁止把关联了ST状态的引用(如STRef s a)泄露到纯代码层面——否则会打破ST的状态隔离机制,引发不安全的副作用。
内容的提问来源于stack exchange,提问作者Dmitry Kapustin
相关产品推荐
相关产品推荐

