Вы не можете изменить Char
s внутри MyObject
. В самом деле, вы даже не можете изменить содержимое StablePtr
. Все, что вы можете сделать, это разыменовать StablePtr
, чтобы получить MyObject
обратно.
Если вы определите
newtype MyObject = Obj (IORef String)
(или MVar
вместо IORef
)
тогда вы сможете изменить его обычными методами.
Для чего стоит, если вас беспокоит потребление памяти, String
совсем не подходит; он использует 5 машинных слов на символ . Однако издержки «возврата нового значения» могут быть не такими высокими, как вы думаете: благодаря совместному использованию добавление Char
к String
не копирует всю строку, а вместо этого просто повторно использует ссылку на "Старый. С такими древовидными структурами, как Seq
, эти преимущества переносятся и на замену элементов.
Однако, если вы делаете много мутаций, вы можете рассмотреть изменчивый вектор .
Конечно, если String
является лишь примером (как и следует из вашего последнего абзаца), то этот совет не обязательно применяется. Но если у вас есть
data Huge = Huge { giganticPart :: Gigantic, smallPart :: Int }
тогда myHuge { smallPart = 42 }
не собирается копировать весь Gigantic
, и если Gigantic
является подходящей древовидной структурой, вы сможете вносить в нее изменения, не копируя все это. Это основная идея чисто функциональных, постоянных структур данных и одно из важнейших преимуществ Haskell.