Как переписать функцию 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