Haskell + StablePtr - PullRequest
       1

Haskell + StablePtr

2 голосов
/ 23 января 2012

У меня есть функция C, вызывающая Haskell.Функция C передает StablePtr типа данных Haskell, и код Haskell должен изменить некоторые из его значений.Какой эффективный способ сделать это?Например, рассмотрим следующее

foreign export ccall editChar :: StablePtr MyObject -> CInt -> CChar -> IO ()

data MyObject = Obj String

editChar :: StablePtr MyObject -> CInt -> CChar -> IO ()
editChar cMyObjectPtr index newChar = do
  -- Code goes here

Как будет реализован editChar, чтобы он был настолько эффективным и насколько возможно Haskelly, чтобы установить Char на index на newChar ?В конечном итоге объект, который будет мутирован, будет иметь довольно большой объем памяти и иметь много подкомпонентов, поэтому возврат нового объекта в результате editChar исключен.

1 Ответ

4 голосов
/ 23 января 2012

Вы не можете изменить 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...