haskell - ST类封装

标签 haskell polymorphism encapsulation phantom-types rank-n-types

我正在尝试使用类型系统来确保永远不会从 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 中的类似代码会抛出错误而我的不会?据我了解 sM s a应该成为约束,使 sX s一个自由类型变量,从而导致类型检查器出错。

最佳答案

要强制执行类型抽象,您必须使用 datanewtype ,而不是 type .
type 中未使用的参数同义词根本没有效果:

type M s = State Int

所以这些是等价的:
newX :: M s (X s)
newX :: State Int (X s)

eval :: (forall s. M s a) -> a
eval :: State Int a -> a
eval实际上不是更高级别的。

关于haskell - ST类封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60058614/

相关文章:

Haskell:使用 UNPACK Pragma 的 GADT

haskell - 以更优化的方式反转自己的列表

haskell - 为什么此功能无法进行类型检查?

haskell - 多类组合

haskell - 如何根据列的值从列表中删除行

java - java 如何反序列化一个类不在类路径上但其父类(super class)在的对象?

function - 是否可以在不丢失 ocaml 中参数的多态类型的情况下设置函数的默认值

c - C中的可重入库设计

c# - 如何在 C# 中查找在当前范围之外定义的变量?

ios - Swift中AppDelegate变量的封装