状态,ST,IORef和MVar之间的区别 [英] Difference between State, ST, IORef, and MVar

查看:154
本文介绍了状态,ST,IORef和MVar之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 48小时写自己的计划(我达到约85小时)已经了解了关于添加变量和分配的部分。这一章有一个很大的概念上的跳跃,我希望它在两个步骤中完成了重构,而不是直接跳到最后的解决方案。无论如何... ...

我已经迷失了许多不同的类,它们似乎有着相同的目的: State ST IORef MVar 。文中提到了前三个,而最后一个似乎是关于前三个StackOverflow问题的回答。它们似乎都在连续的调用之间进行了一次状态。



这些都是什么,它们又有什么不同?






特别是这些句子没有意义:


我们使用称为状态线程的功能,让Haskell为我们管理聚合状态。这让我们可以像使用任何其他编程语言那样处理可变变量,使用函数来获取或设置变量。


IORef模块允许您使用IO monad中的有状态变量




所有这些都使得类型ENV = IORef [(String,IORef LispVal)] 令人困惑 - 为什么第二个 IOREF ?如果我写类型ENV = State [(String,LispVal)] ,那么会破坏什么?

State Monad:一种可变状态模型



状态monad是一个纯粹功能性的程序环境与状态,用一个简单的API:




  • 得到

  • 放置



mtl包



State monad通常用于需要单个控制线程中的状态。它在实现中实际上并不使用可变状态。相反,程序由状态值参数化(即状态是所有计算的附加参数)。状态只在单个线程中出现突变(并且不能在线程间共享)。



ST monad和STRefs



ST monad是IO monad的受限表亲。



它允许任意可变状态 >,实现为机器上的实际可变内存。在无副作用的程序中,API是安全的,因为rank-2类型参数可防止依赖于可变状态的值从本地作用域转义出来。



因此,它允许在其他纯程序中控制可变性。

常用于可变数组和其他数据结构,这些数据结构发生了变异,然后被冻结。这也是非常有效的,因为可变状态是硬件加速。

主要API:


    < li< href = / b>
  • runST - 启动一个新的记忆效应计算。

  • STRefs :指向(本地)可变单元格的指针。
  • ST- (如向量)也很常见。


将其视为IO monad的危险性较低的同胞。或IO,只能读写内存。



IORef:IO中的STRefs



这些是IO monad中的STRefs(参见上文)。他们没有与STRefs相同的安全保证。



MVars:带锁的IORefs



像STRefs或IORefs一样,但附加了一个锁,用于从多个线程安全地并发访问。使用 atomicModifyIORef (比较和交换原子操作)时,IORefs和STRefs在多线程设置中仅是安全的。通常,在Haskell中,通过STRef或IORef使用MVars或TVars(基于STM的可变单元格)。

/ p>

I am working through Write Yourself a Scheme in 48 Hours (I'm up to about 85hrs) and I've gotten to the part about Adding Variables and Assignments. There is a big conceptual jump in this chapter, and I wish it had been done in two steps with a good refactoring in between rather then jumping at straight to the final solution. Anyway…

I've gotten lost with a number of different classes that seem to serve the same purpose: State, ST, IORef, and MVar. The first three are mentioned in the text, while the last seems to be the favored answer to a lot of StackOverflow questions about the first three. They all seem to carry a state between consecutive invocations.

What are each of these and how do they differ from one another?


In particular these sentences don't make sense:

Instead, we use a feature called state threads, letting Haskell manage the aggregate state for us. This lets us treat mutable variables as we would in any other programming language, using functions to get or set variables.

and

The IORef module lets you use stateful variables within the IO monad.

All this makes the line type ENV = IORef [(String, IORef LispVal)] confusing - why the second IORef? What will break if I'll write type ENV = State [(String, LispVal)] instead?

解决方案

The State Monad : a model of mutable state

The State monad is a purely functional environment for programs with state, with a simple API:

  • get
  • put

Documentation in the mtl package.

The State monad is commonly used when needing state in a single thread of control. It doesn't actually use mutable state in its implementation. Instead, the program is parameterized by the state value (i.e. the state is an additional parameter to all computations). The state only appears to be mutated in a single thread (and cannot be shared between threads).

The ST monad and STRefs

The ST monad is the restricted cousin of the IO monad.

It allows arbitrary mutable state, implemented as actual mutable memory on the machine. The API is made safe in side-effect-free programs, as the rank-2 type parameter prevents values that depend on mutable state from escaping local scope.

It thus allows for controlled mutability in otherwise pure programs.

Commonly used for mutable arrays and other data structures that are mutated, then frozen. It is also very efficient, since the mutable state is "hardware accelerated".

Primary API:

  • Control.Monad.ST
  • runST -- start a new memory-effect computation.
  • And STRefs: pointers to (local) mutable cells.
  • ST-based arrays (such as vector) are also common.

Think of it as the less dangerous sibling of the IO monad. Or IO, where you can only read and write to memory.

IORef : STRefs in IO

These are STRefs (see above) in the IO monad. They don't have the same safety guarantees as STRefs about locality.

MVars : IORefs with locks

Like STRefs or IORefs, but with a lock attached, for safe concurrent access from multiple threads. IORefs and STRefs are only safe in a multi-threaded setting when using atomicModifyIORef (a compare-and-swap atomic operation). MVars are a more general mechanism for safely sharing mutable state.

Generally, in Haskell, use MVars or TVars (STM-based mutable cells), over STRef or IORef.

这篇关于状态,ST,IORef和MVar之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆