我有this simple project我尝试使用Haskell和Cairo库。
我遇到了重新绘制应用程序状态的问题。目前我拥有拥有全球状态的记录。我必须将它存储在Data.IORef
monad中,以便能够将数据从一个GUI事件传递到另一个GUI事件。
我受到榆树的启发,尝试这样做,但我想知道是否有更好的方法可以做到这一点?
我特别关注主要功能中的这个片段。
-- update globalModel in place
readIORef globalModel >>= (\m -> writeIORef globalModel (Model
(fromIntegral kv)
(if ((keyToHeading (fromIntegral kv)) == None)
then (heading m)
else (keyToHeading (fromIntegral kv)))))
请提出更好的方法。
答案 0 :(得分:4)
这可能是一个更简单的重构。请注意,modifyIORef'
将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)
Header
的一个小实用程序函数ifNoneThen
(您也可以在其他地方使用)清除代码正文中的if
语句。fromIntegral kv
3次?)。IORef
)中分解出来,可以更容易地推理代码 - 意外副作用的地方更少突然出现。