小编Sou*_*per的帖子

ST样封装

我正在尝试使用类型系统来确保 X 永远不会从 monad M 中取出。我希望它的工作类似于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
Run Code Online (Sandbox Code Playgroud)

但是,以下代码不会导致类型错误:

ghci> x = eval newX
ghci> :t x
x :: X s
Run Code Online (Sandbox Code Playgroud)

为什么 ST monad 中的类似代码会抛出错误而我的不会?根据我的理解,sinM s a应该被绑定,使sinX s成为自由类型变量,从而导致类型检查器出错。

polymorphism haskell encapsulation phantom-types rank-n-types

6
推荐指数
1
解决办法
71
查看次数