Язык C предоставляет очень удобный способ обновления nth
элемента массива: array[n] = new_value
. Насколько я понимаю, тип Data.ByteString
таков, что он обеспечивает функциональность, очень похожую на массив C из uint8_t
— доступ через index :: ByteString -> Int -> Word8
. Оказывается, обратная операция — обновление значения — не так проста.
Мой первоначальный подход заключался в использовании функций take
, drop
и singleton
, concat
etaned следующим образом:
updateValue :: ByteString -> Int -> Word8 -> ByteString
updateValue bs n value = concat [take (n-1) bs, singleton value, drop (n+1) bs]
(это очень наивная реализация, поскольку она не обрабатывает крайние случаи)
Учитывая фон C, он кажется немного слишком тяжелым, чтобы вызывать 4 функции для обновления одного значения. Теоретически сложность операции не так уж и плоха:
take
is O(1)drop
is O(1)singleton
is O(1)concat
равно O(n), но здесь я не уверен, является ли n полной длиной составного списка или в нашем случае это просто 3.
Мой второй подход заключался в том, чтобы попросить у Hoogle функцию с похожей сигнатурой типа: ByteString -> Int -> a -> ByteString
, но ничего подходящего не появилось.
Я упустил что-то очень очевидное или действительно сложно обновить значение?
Я хотел бы отметить, что я понимаю тот факт, что ByteString
является неизменяемым и что изменение любого из его элементов приведет к созданию нового экземпляра ByteString
.
РЕДАКТИРОВАТЬ: возможное решение, которое я нашел, читая о библиотеке Control.Lens
, использует линзу set
. Ниже приведен отрывок из GHCi с опущенными именами модулей:
> import Data.ByteString
> import Control.Lens
> let clock = pack [116, 105, 99, 107]
> clock
"tick"
> let clock2 = clock & ix 1 .~ 111
> clock2
"tock"
map
. Можете ли вы объяснить немного больше о том, что вы в конечном итоге после? - person MathematicalOrchid   schedule 19.11.2015ByteString
в качестве резервного хранилища памяти. Речь идет о десятках байт. Приходит инструкция, и ее выполнение изменяет определенный байт памяти, например.mov 4, mem7
(и здесь в дело вступает наша функцияupdateValue
). Поэтомуmap
ping здесь не вариант. Что может быть важным дополнением, так это то, что в этом случае производительность является серьезной проблемой. - person Daniel Lovasko   schedule 19.11.2015