看这里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
.那么为什么在 read 和 length 之间做出这种设计选择的差异,因为它们都是向量上的不可变操作?
现在我想一想,read返回的单元格是否是对向量内单元格的引用而不是其数据的副本?
如果是这样,我怎样才能又好又便宜地获得对可变向量中第 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
必须是一元 Action 。这与
length
不同。 .向量的长度永远不会改变,即使向量是可变的;创建时固定的长度。因此,length
是一个纯函数;在创建向量和查询其长度之间执行了什么单子(monad)操作并不重要;它总是一样的。
关于haskell - 为什么 Data.Vector.Mutable read() 会在 monad 中返回,因为它是不可变的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58330593/