Краткий ответ: есть системы, позволяющие вам делать то, что вы хотите. Например, вы можете сделать это, используя монаду ST
в Haskell (как указано в комментариях).
Монадный подход ST
взят из Control.Monad.ST
Хаскелла. Код, написанный в монаде ST
, может использовать ссылки (STRef
) там, где это удобно. Приятной особенностью является то, что вы даже можете использовать результаты монады ST
в чистом коде, так как она по сути автономна (это в основном то, что вы хотели в этом вопросе).
Доказательство этого автономного свойства осуществляется через систему типов. Монада ST
содержит параметр потока состояния, обычно обозначаемый переменной типа s
. Когда у вас есть такое вычисление, вы получите монадический результат с типом:
foo :: ST s Int
Чтобы на самом деле превратить это в чистый результат, вы должны использовать
runST :: (forall s . ST s a) -> a
Вы можете прочитать этот тип как: дайте мне вычисление, где параметр типа s
не имеет значения, и я могу вернуть вам результат вычисления без багажа ST
. Это, в основном, препятствует выходу изменчивых переменных ST
, так как они будут нести s
с ними, что будет обнаружено системой типов.
Это может быть использовано для хорошего воздействия на чистые структуры, которые реализованы с помощью базовых изменяемых структур (например, vector package ). Можно отказаться от неизменности на ограниченное время, чтобы сделать что-то, что изменяет основной массив на месте. Например, можно объединить неизменный Vector
с пакетом нечистых алгоритмов , чтобы сохранить большинство характеристик производительности алгоритмов сортировки на месте и при этом получить чистоту.
В этом случае это будет выглядеть примерно так:
pureSort :: Ord a => Vector a -> Vector a
pureSort vector = runST $ do
mutableVector <- thaw vector
sort mutableVector
freeze mutableVector
Функции thaw
и freeze
имеют линейное копирование, но это не нарушит общее время выполнения O (n lg n). Вы даже можете использовать unsafeFreeze
, чтобы избежать другого линейного обхода, поскольку изменяемый вектор больше не используется.