Haskell 中如何实现可变数组?

发布于 2024-11-03 03:56:05 字数 170 浏览 1 评论 0 原文

我读过很多关于这个主题的研究论文,他们通常认为数组是使用 Monad 实现的。但这些论文都没有给出“类型”数组本身应该如何定义的明确定义,它们只给出了使用 monad 访问或修改此类型的函数的定义。 在 Haskell 中如何实现具有 O(1) 时间来访问或修改索引元素的数组?! (例如 STUArray 和 MArray)

I've read many research papers on this topic, and they usually argue that arrays are implemented using Monads. But none of these papers gave a clear definition of how the "type" Array itself should be defined, they only gave definitions for the functions using monads to access or modify this type.
How are arrays, having O(1) time to access or modify an indexed element, implemented in Haskell ?! (such as STUArray and MArray)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

感性不性感 2024-11-10 03:56:05

在 Haskell 中如何实现具有 O(1) 时间访问或修改索引元素的数组

它们是通过运行时系统中用于内存读写的原始操作来实现的。

通过使用 monad 线性化对可变状态的访问,可以确保破坏性写入内存的副作用操作的安全性。

查看 Haskell 数组的 primitive 包(在 IO ST),您可以看到实现是根据 GHC 的 primops

-- | Create a new mutable array of the specified size and initialise all
-- elements with the given value.
newArray :: PrimMonad m => Int -> a -> m (MutableArray (PrimState m) a)
newArray (I# n#) x = primitive
   (\s# -> case newArray# n# x s# of
             (# s'#, arr# #) -> (# s'#, MutableArray arr# #))

-- | Read a value from the array at the given index.
readArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> m a
readArray (MutableArray arr#) (I# i#) = primitive (readArray# arr# i#)

-- | Write a value to the array at the given index.
writeArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray (MutableArray arr#) (I# i#) x = primitive_ (writeArray# arr# i# x)

也就是说,

  • newArray#
  • readArray#
  • writeArray#

是用于在语言提供的内存上进行操作的原始(硬件加速;)服务运行时。

Launchbury 和 Peyton-Jones 的论文 惰性功能状态线程,它引入了 ST monad 和可变数组的原语。

How are arrays, having O(1) time to access or modify an indexed element, implemented in Haskell

They are implemented via primitive operations in the runtime system for memory reads and writes.

The safety of the side effecting action of destructively writing to memory is ensured via the use of monads to linearize access to the mutable state.

Looking at the primitive package for Haskell arrays (in IO or ST), you can see that the implementations is in terms of GHC's primops:

-- | Create a new mutable array of the specified size and initialise all
-- elements with the given value.
newArray :: PrimMonad m => Int -> a -> m (MutableArray (PrimState m) a)
newArray (I# n#) x = primitive
   (\s# -> case newArray# n# x s# of
             (# s'#, arr# #) -> (# s'#, MutableArray arr# #))

-- | Read a value from the array at the given index.
readArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> m a
readArray (MutableArray arr#) (I# i#) = primitive (readArray# arr# i#)

-- | Write a value to the array at the given index.
writeArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray (MutableArray arr#) (I# i#) x = primitive_ (writeArray# arr# i# x)

That is, in terms of:

  • newArray#
  • readArray#
  • writeArray#

which are primitive (hardware accelerated ;) services for operating on memory provided by the language runtime.

Mechanisms for giving type safety to destructive memory effects were introduced to Haskell by the Launchbury and Peyton-Jones paper, Lazy Functional State Threads, which introduces the ST monad and primitives for mutable arrays.

变身佩奇 2024-11-10 03:56:05

顺便说一句,请记住,“使用 monad 实现”(可以对各种控制结构执行)与“通过不透明类型上的一元操作隔离的副作用”实际上并不相同,如 IOST,其中 monad 的属性仅确保纯代码保持不变。

正如 Don Stewart 所解释的那样,可变数据作为运行时原语提供;这里唯一“用 monad 实现”的是类型安全。

As something of an aside, please keep in mind that "implemented using monads", as can be done for various control structures, is not really the same thing as "side effects isolated by monadic operations on an opaque type", as with IO or ST, where the properties of the monad merely ensure that pure code remains so.

The mutable data is provided as a runtime primitive, as Don Stewart explains; the only thing "implemented with monads" here is type safety.

oО清风挽发oО 2024-11-10 03:56:05

它们的实现方式与命令式语言相同;即就地更新。类型系统将保证你不能用它们做任何“坏”的事情。

They are implemented in the same way as in an imperative language; i.e., in-place update. The type system will guarantee that you can't do anything "bad" with them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文