如何理解Haskell';圣莫纳德酒店

如何理解Haskell';圣莫纳德酒店,haskell,types,monads,states,Haskell,Types,Monads,States,Jones和Launchbury在他们的“惰性功能状态线程”中描述了ST monad。到 确保可变变量不能在已创建的上下文(或“线程”)之外使用 在中,他们使用特殊类型,包括更高级别的类型。这里有四个重要的例子: newVar :: ∀ s a. a -> ST s (MutVar s a) readVar :: ∀ s a. MutVar s a -> ST s a writeVar :: ∀ s a. MutVar s a -> a -> ST s () run

Jones和Launchbury在他们的“惰性功能状态线程”中描述了ST monad。到 确保可变变量不能在已创建的上下文(或“线程”)之外使用 在中,他们使用特殊类型,包括更高级别的类型。这里有四个重要的例子:

newVar   :: ∀ s a. a -> ST s (MutVar s a)
readVar  :: ∀ s a. MutVar s a -> ST s a
writeVar :: ∀ s a. MutVar s a -> a -> ST s ()
runST    :: ∀   a. (∀ s. ST s a) -> a
为了了解这种结构背后的想法,我阅读了论文的前两部分。这个 以下解释似乎是核心:

现在,我们真正想说的是,
newST
应该只应用于使用
newVar
创建该线程中使用的任何引用的状态转换器。换句话说,
runST
的参数不应该对初始状态中已经分配的内容进行任何假设。也就是说,
runST
应该工作,而不管它的初始状态是什么。所以
runST
的类型应该是:
runST::∀ A.(∀ s、 ST s a)->a

解释很好,但我想知道它如何映射到所需类型的最终定义。我的 问题是我不知道如何解释类型变量
s
。如第1节所述,国家 本质上是从变量到值的映射。但是什么是状态类型?一个国家能在什么情况下生存 类型
s
不同于另一类型
t
?对我来说,有两种可能性:

(1) 类型
s
可以被视为变量映射的具体类型,例如列表、数组 序列可以看作是序列集合的具体类型。(我故意避开这里 “类”和“实现”这两个词,因为
s
的类型没有类限制)

(2) 类型
s
可以看作是一个具体的值,即一个具体的状态,即 变量

解释(2)很好地符合Jones和Launchbury对
runST
类型的解释。这个 所有量化表示实际状态的独立性(由 状态类型)。然而,这种解释中的缺陷是
writeVar
类型。显然 修改状态,其类型应为
∀ 是的。MutVar s a->a->ST t()
。那么这个 解释必须是错误的

然而,解释(1)并不是真的更好,因为它没有映射到琼斯和Launchbury的 解释。类型
∀ 是的。对于
runST
,ST s a->a
就可以了。重要的是 对于给定的状态(类型为
s
)的具体值,不能有任何假设 对函数进行修改。因此,所有的量化不应该超过状态类型,而是(相反)超过状态类型 国家的具体价值。类型系统必须表示有状态的 指定给
runST
的操作独立于状态(但不独立于其类型)

因此,我的两种解释都是错误的。我真的尽力去理解这类事情 建设有人能给我解释一下吗

另外,我已经读过了 但这对我没有帮助,什么时候 我用我的手做统一算法,我看到了机制的工作原理和工作方式(通过
使用范围限制)但我真的想理解它——而不仅仅是看它是否有效。

我会避免将
s
解释为任何具体的东西。它基本上只是一个“唯一标识符”这确保了两个不同的
ST
计算中的状态不会混淆。特别是,因为
runST
的参数是a(秩-2)多态动作,你可以从这个一元动作中偷偷带出的任何状态引用都必然是一种存在类型,而且基本上你无法使用无约束的存在类型。因此,不可能引用状态一元中实际上不存在的值

如果你想把代码> S/<代码>看作是具体的东西,就把它看作是一个可以分配、修改和删除状态值的世界的类型。 该设置中的类型说明:

  • newVar::∀ s a.a->ST s(MutVar s a)
    :在任何世界
    s
    ,我都能够将
    a
    类型的值扔到地上,这样就可以通过
    MutVar
    引用(当然,只有在同一个世界中–虽然这个世界的状态因此而改变,但它的类型/身份不会改变)
  • readVar::∀ s a.MutVar s a->ST s a
    :如果可变引用与我生活在同一个世界中,我可以查看对象并将一个副本作为一元结果提供给您
  • writeVar::∀ s a.MutVar s a->a->ST s()
    :如果可变引用与我生活在同一个世界中,我就能够销毁位于那里的对象,并用其他对象替换它
  • runST::∀   a(∀ s、 圣马力诺(圣马力诺)->a
    :给定一个在任何世界都有效的动作,我能够选择一些无人知晓的隐藏星球。该动作可能会将各种变异的暴行应用到景观中,只带来结果。因为没有人知道这个星球,所以我们仍然有一个宇宙,每个人都能看到,它毫发无损,完全正常运行,但你不能得到破坏性计算的结果
解释很好,但我想知道它如何映射到所需类型的最终定义

好的,让我们回到我们正在尝试做的事情,以及它与我们已经可以做的事情的区别

功能状态线程 我们已经可以做函数状态了。这是用
状态s
单子完成的,其中
状态sx::*
同构于函数类型
s->(x,s)
:函数将
s
作为输入,并返回一对包含类型的值