如何正确更新Data.IORef中保存的Haskell记录?
我曾经尝试过Haskell和开罗图书馆 我在重新绘制应用程序的状态时遇到问题。目前,我有记录,持有全球国家。我必须将它存储在如何正确更新Data.IORef中保存的Haskell记录?,haskell,Haskell,我曾经尝试过Haskell和开罗图书馆 我在重新绘制应用程序的状态时遇到问题。目前,我有记录,持有全球国家。我必须将它存储在Data.IORefmonad中,以便能够将数据从一个GUI事件传递到另一个GUI事件 我是受Elm的启发尝试这样做的,但我想知道是否有更好的方法 我特别关注main函数中的这个片段 -- update globalModel in place readIORef globalModel >>= (\m -> writeIORef globalModel
Data.IORef
monad中,以便能够将数据从一个GUI事件传递到另一个GUI事件
我是受Elm的启发尝试这样做的,但我想知道是否有更好的方法
我特别关注main函数中的这个片段
-- update globalModel in place
readIORef globalModel >>= (\m -> writeIORef globalModel (Model
(fromIntegral kv)
(if ((keyToHeading (fromIntegral kv)) == None)
then (heading m)
else (keyToHeading (fromIntegral kv)))))
请建议更好的方法。这可能是一个更简单的重构。请注意,将
readIORef
和writeIORef
组合成一个严格的操作:
ifNoneThen :: Heading -> Heading -> Heading
None `ifNoneThen` x = x
h `ifNoneThen` _ = h
updateModel :: Int -> Model -> Model
updateModel kv oldModel = Model newKv newHeading
where newKv = fromIntegral kv
newHeading = keyToHeading newKv `ifNoneThen` heading oldModel
foo :: Int -> Model -> IO ()
foo kv globalModel = modifyIORef' globalModel (updateModel kv)
- 一个用于
s的小型实用程序函数,标题
(您也可以在其他地方使用)清理代码主体中的ifnoneten
语句if
- 一些小的重构来删除重复的调用(如果可以调用一次并给结果起一个有意义的名字,为什么要调用
3次?)fromIntegral kv
- 将纯代码(从旧模型构建新模型)从非纯代码(更新
)中分解出来,可以更容易地对代码进行推理-出现意外副作用的地方更少IORef
IORef
不是monad。它表明我是noob:-)为什么不考虑从IORef
业务中更改模型?后者类似于modifyIORef'
。非常感谢。今天我学到了关于Haskell的新东西。在某些情况下,使用modifyIORef会导致问题@ruby_object这是对原始代码的语义等效重构(避免在新模型中过于严格)-听起来多线程不是您原始问题的考虑因素。