当我尝试在 GHC 7.4.1 下加载以下代码时:
{-# LANGUAGE RankNTypes #-}
import Control.Monad.ST
newtype M s a = M { unM :: ST s a }
runM :: (forall s. M s a) -> a
runM (M m) = runST m
它失败并显示以下消息:
test.hs:9:14:
Couldn't match type `s0' with `s'
because type variable `s' would escape its scope
This (rigid, skolem) type variable is bound by
a type expected by the context: ST s a
The following variables have types that mention s0
m :: ST s0 a (bound at test.hs:9:9)
In the first argument of `runST', namely `m'
In the expression: runST m
In an equation for `runM': runM (M m) = runST m
为什么这会失败,什么时候M
只是一个包装器ST
?
(我的实际程序在顶部堆叠了一些变压器——这只是一个最小的例子。)
编辑:似乎添加let
解决了这个问题:
runM m = let M m' = m in runST m
但是,如果TypeFamilies
启用(就像在我的真实代码中一样),它会再次失败。