Как массивы, имеющие O (1) время для доступа или изменения индексированного элемента, реализованы в Haskell
Они реализованы посредством простых операций в системе времени выполнения для чтения и записи в память.
Безопасность побочного действия деструктивной записи в память обеспечивается использованием монад для линеаризации доступа к изменяемому состоянию.
Глядя на пакет primitive
для массивов Haskell (в IO
или ST
), вы можете видеть, что реализации в терминах 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 #
, которые являются примитивными (с аппаратным ускорением;) сервисами для работы с памятью, предоставляемой языковой средой исполнения.
Механизмы обеспечения безопасности типов для деструктивных эффектов памяти были введены в Haskell в статье Launchbury и Peyton-Jones, Lazy Functional State Threads , которая представляет монаду ST
и примитивы для изменяемых массивов.