Как реализуются изменяемые массивы в Haskell?

Я прочитал много исследовательских работ по этой теме, и они обычно утверждают, что массивы реализуются с использованием монад. Но ни одна из этих статей не дала четкого определения того, как должен быть определен сам массив" тип", они только дали определения для функций, использующих монады для доступа или изменения этого типа. Как массивы, имеющие O (1) время для доступа или изменения индексированного элемента, реализуются в Haskell ?! (например, STUArray и Мэррей)

3 ответов


как массивы, имеющие O (1) время для доступа или изменения индексированного элемента, реализованы в Haskell

они реализованы с помощью примитивных операций в системе выполнения для чтения и записи памяти.

безопасность стороны производя действие деструктивно сочинительства к памяти обеспечена через пользу монад линеаризовать доступ к mutable состоянию.

смотреть на!--14-->primitive пакет для массивов Haskell (в 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 и Пейтон-Джонс бумаги, Ленивые Потоки Функционального Состояния, который вводит ST монады и примитивы для изменяемых массивов.


они реализованы так же, как и на императивном языке; т. е. обновление на месте. Система типов гарантирует, что вы не сможете сделать с ними ничего "плохого".


в качестве чего-то в стороне, пожалуйста, имейте в виду, что "реализовано с использованием монад", как это может быть сделано для различных структур управления, на самом деле не то же самое, что "побочные эффекты, изолированные монадическими операциями на непрозрачном типе", как с IO или ST, где свойства монады просто гарантируют, что чистый код остается таким.

изменяемые данные предоставляются как примитив времени выполнения, как объясняет Дон Стюарт; единственное, что "реализовано с монадами" здесь-тип безопасность.