面向新手的 STArray 文档和状态/ST 相关问题
我很难从文档和通过 Google 找到的其他操作/讨论中理解 STArray
。下面我还有一些相关问题。
根据文档,STArray
是
ST monad 中的可变装箱和未装箱数组。
这给我的印象是,STArray
旨在用作在函数之间传递的状态(想象一下您有一个必须经常更新的向量)。
显然,这的用法有所不同:
ST s (STArray s a e)
这里的状态 s
是什么?如果是内部使用,那为什么不对用户隐藏呢?
这也意味着,如果我们想使用 STArray s Int Int 作为状态传递,则需要定义
type StateArray a = Control.Monad.State (ST s (STArray s Int Int)) a
这似乎相当麻烦。
最后,
ST
和State
之间有什么区别?- 如果
ST
和IO
供“内部”使用,那么STArray
和IOArray
之间有什么区别?
谢谢你!!
I have a hard time to understand STArray
from the documentation and other howtos/discussion I've found through Google. I've got some more related questions below.
According to the documentation, STArray
s are
Mutable boxed and unboxed arrays in the ST monad.
This gave me the impression, that STArray
is meant to be used as a state being passed around between functions (imagine you have a vector that has to be updated often).
Apparently this is used differently though:
ST s (STArray s a e)
What is the state s
here? If it is used internally, then why is this not hidden from the user?
This also means, if we want to use a STArray s Int Int
being passed around as state, one would define
type StateArray a = Control.Monad.State (ST s (STArray s Int Int)) a
which seems rather cumbersome.
Finally,
- what is the difference between
ST
andState
? - what is the difference between
STArray
andIOArray
, if theST
andIO
are meant for "internal" use?
Thank you!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ST
是一个 monad,其中允许有限类型的副作用,即可变引用和可变数组。因此,它允许您实现从外部世界看来是纯粹的函数,但在内部使用突变。这与
State
不同,后者仅通过将状态作为额外的输入和输出通过计算进行线程化来伪造突变。在实现一些命令式算法时,这种差异很重要,因为它们有时需要突变才能有效实现。例如,在State
单子中使用常规数组,您只能通过制作副本来修改它,而使用ST
您可以就地进行真正的突变。之所以我们同时拥有
ST
和IO
,是因为ST
提供了比IO
更强的保证,即:ST
不允许任意副作用,例如访问文件系统。ST
does 允许的副作用无法逃脱runST
的作用域,因此从外界来看它可以被视为纯粹的。之所以能保证副作用无法逃逸,与类型变量
s
有关。由于任何 ST 操作在s
中都必须是多态的,因此您无法编写允许任何可变引用进入或离开runST
范围的代码,因为类型检查器会抱怨它不能保证您的操作的s
与引用或数组的s
相同,除非它们来自相同的runST
作用域。作为将
ST
monad 与可变数组结合使用的示例,以下是埃拉托斯坦筛法的实现:runSTUArray
是runST< 的特殊形式/code> 它允许您在冻结数组并将其作为不可变数组返回之前使用内部突变来构建数组。
newArray
、readArray
和writeArray
执行您所期望的操作。如您所见,
sieve 的类型签名
表明它是一个纯函数,确实如此。然而,它在内部大量使用突变来有效地实现它。ST
is a monad in which a limited type of side effects are allowed, namely mutable references and mutable arrays. Thus it allows you to implement functions which are pure as seen from the outside world, but which use mutation internally.This is different from
State
, which only fakes mutation by threading the state through your computation as extra inputs and outputs. The difference is important when implementing some imperative algorithms, because they sometimes need mutation to be implemented efficiently. For example using a regular array in aState
monad, you can only modify it by making a copy, whereas withST
you can have true mutation in-place.The reason why we have both
ST
andIO
is thatST
provides stronger guarantees thanIO
, namely:ST
does not allow arbitrary side effects like for example accessing the file system.ST
does allow cannot escape the scope ofrunST
, and so it can be seen as pure from the outside world.The reason why we can guarantee that the side effects cannot escape is related to the type variable
s
. Since any ST action must be polymorphic ins
, you cannot write code which allows any mutable references to enter or leave the scope of arunST
, because the type checker will complain that it cannot guarantee that thes
of your action and that of the reference or array are the same unless they come from the samerunST
scope.As an example of using the
ST
monad with mutable arrays, here is an implementation of the Sieve of Erathostenes:runSTUArray
is a specialized form ofrunST
which allows you to build an array using mutation on the inside, before freezing it and returning it as an immutable array.newArray
,readArray
andwriteArray
do what you'd expect.As you can see, the type signature of
sieve
indicates that it's a pure function, and it is. However, it uses mutation heavily on the inside to implement it efficiently.