[我正在尝试使用类型系统来确保永远不会从monad M中取出X。我希望它的工作方式类似于runST
,在这里无法混合来自不同线程的环境。
data X s = X Int
type M s = State Int
newX :: M s (X s)
newX = X <$> get
eval :: (forall s. M s a) -> a
eval x = evalState x 0
但是以下代码不会引起类型错误:
ghci> x = eval newX
ghci> :t x
x :: X s
为什么ST monad中的类似代码会引发错误,而我的不会?据我了解,s
中的M s a
应该成为绑定,使s
中的X s
为自由类型变量,从而导致类型检查器出错。
要强制类型抽象,必须使用data
或newtype
,而不是type
。