【问题标题】:How are mutable arrays implemented in Haskell?Haskell 中的可变数组是如何实现的?
【发布时间】:2011-04-25 04:53:27
【问题描述】:

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

【问题讨论】:

  • 通常它们是通过调用外部库或 RTS 支持来实现的。
  • 我想知道“数组是使用 Monads 实现的”是什么意思……听起来像“面包是用桌子烤的”。
  • @Alexey “implemented”在英文中的意思是“生效”。所以说 Haskell 中数组的可变性是使用 Monads 实现(“生效”或“实现”)的,这并没有错。使用无限流也可以实现相同的结果,但直观性要差得多。

标签: arrays haskell state monads mutable


【解决方案1】:

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

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

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

查看用于 Haskell 数组的 primitive 包(在 IOST 中),您可以看到实现是在 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)

也就是说,就:

  • newArray#
  • readArray#
  • writeArray#

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

Launchbury 和 Peyton-Jones 的论文 Lazy Functional State Threads 向 Haskell 介绍了为破坏性记忆效应提供类型安全的机制,该论文介绍了可变数组的 ST monad 和原语。

【讨论】:

    【解决方案2】:

    顺便说一句,请记住“使用 monad 实现”,就像对各种控制结构所做的那样,与“通过不透明类型上的 monadic 操作隔离的副作用”实际上并不是一回事,因为使用IOST,monad 的属性只是确保纯代码保持不变。

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

    【讨论】:

    • 类型安全封装排序(自动线程化的s参数,给出效果的依赖顺序)。
    • @Don:啊,是的,我想我认为那部分已经很明显了,但你说得对,我应该更明确一点。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2012-01-18
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      相关资源
      最近更新 更多