Как переписать функцию Haskell, которая использует modifyIORef для использования atomicModifyIORef

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

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

Это мой код:

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

Мои выводы

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

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

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

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

1 ответ

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

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
Другие вопросы по тегам