看这里http://hackage.haskell.org/package/vector-0.12.0.3/docs/Data-Vector-Mutable.html可以看到读取的类型是:
read :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
由于读操作不会修改向量,所以我的主要问题是为什么不这样做:
read :: PrimMonad m => MVector (PrimState m) a -> Int -> a
可变向量的长度也在向量上做不可变的事情,其类型为MVector s a -> Int
,看起来很正常。不是PrimMonad m => MVector (PrimState m) a -> m Int
。那么为什么在读取和长度之间做出设计选择的差异,因为它们都是向量上的不变操作?
现在,我考虑一下,以某种方式读取返回的单元格是对向量内单元格的引用,而不是其数据的副本吗?如果是这样,我怎么能以可变的向量很好且廉价地获得对第n个元素的不变访问?我正在学习haskell,不太了解细节。
谢谢,
考虑
foo = do
...
x1 <- read vector 3
write vector 3 something
x2 <- read vector 3
return (x1 == x2)
如果read
变成非单字母,我们可以改写这个
foo = do
...
let x1 = read vector 3
write vector 3 something
let x2 = read vector 3
return (x1 == x2)
通过参照透明性等同于
foo = do
...
let x1 = read vector 3
write vector 3 something
let x2 = x1
return (x1 == x2)
这里,最后一个代码段总是在最后返回True
,而第一个代码则不。因此,这两个片段不相等。
必须将读取视为一种效果,不是因为它可以从外部观察到(不是),而是因为根据矢量的状态它会产生不同的结果,这取决于写入的影响。