如何重写使用modifyIORef'来使用atomicModifyIORef'的Haskell函数

时间:2018-05-20 12:13:38

标签: haskell ioref

我正在尝试解决Haskell为相同参数提供不同输出的问题。有人已经建议它可能是与线程相关的问题。

我设法重写了一个简单的函数来使用原子版本,但是对于更复杂的函数我需要帮助。

这是我的代码:

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

我的发现

按照建议我尝试使用do notation重写函数:

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 个答案:

答案 0 :(得分:0)

解决问题的关键是使用do notation重写函数。

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