在这里查看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,但不太了解细节。
谢谢,
假设
read :: MVector s a -> Int -> a
这意味着read
是纯粹的。考虑
main :: IO () main = do cell <- replicate 1 'a' -- cell = ['a'] print $ read cell 1 -- we want to print 'a' write cell 1 'z' -- cell = ['z'] print $ read cell 1 -- we want to print 'z'
有什么地方出了问题:我写了read cell 1
两次,传递相同 cell
和1
参数,所以两个调用应该返回相同的值。这就是read
纯粹的意思。以上应等于
main :: IO () main = do cell <- replicate 1 'a' -- cell = ['a'] let cOntents= read cell 1 -- cOntents= 'a' print contents -- prints 'a' write cell 1 'z' -- cell = ['z']; definitely should not affect contents print contents -- prints 'a'
但是我们不希望这样:read
即使在传递相同的参数时,我们也想返回不同的东西,要考虑到write
它们之间可能发生的任何变化。因此,read
必须采取单行动。
这与有所不同length
。即使向量是可变的,向量的长度也不会改变。在创建时固定的长度。因此,length
是一个纯函数;在创建矢量和查询其长度之间执行了什么单调操作都无关紧要;它将永远是相同的。