Как переписать функцию Haskell, которая использует modifyIORef для использования atomicModifyIORef - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь решить проблему, когда Haskell дает разные выходные данные для одних и тех же аргументов.кто-то уже предположил, что это может быть проблема, связанная с потоками.

Мне удалось переписать простую функцию для использования атомарной версии, но с более сложной мне нужна помощь.

Это мойкод:

timeFun globalModel canvas = modifyIORef' globalModel (updateGlobalModel Tick) >> Gtk.widgetQueueDraw canvas >> return True

Мои выводы

Следуя совету, я попытался переписать функцию, используя нотацию do:

timerFun g c = do
  i <- readIORef g
  writeIORef g (updateGlobalModel Tick i)
  Gtk.widgetQueueDraw c
  return True

Версия, которая использует атомарный код и нотацию do:

timerFun g c = do
  atomicModifyIORef' g $ \p -> do
    (updateGlobalModel Tick p ,())
  Gtk.widgetQueueDraw c
  return True

1 Ответ

0 голосов
/ 20 мая 2018

Ключом к решению проблемы было переписывание функции с использованием нотации do.

timerFun g c = do
  i <- readIORef g
  writeIORef g (updateGlobalModel Tick i)
  Gtk.widgetQueueDraw c
  return True

В этот момент у меня было writeIORef отделено от других функций, поэтому переписать его с помощью atomicModifyIORef 'было тривиально.

timerFun g c = do
  atomicModifyIORef' g $ \p -> 
    (updateGlobalModel Tick p, ())
  Gtk.widgetQueueDraw c
  return True

Та же функция с меньшим количеством синтаксического сахара

timerFun g c = (atomicModifyIORef' g (\p -> (updateGlobalModel Tick p, ()))) >>
  Gtk.widgetQueueDraw c >>
  return True
...