我有以下代码来完成更改配置文件的工作:
mutateConfig :: (Config -> Config) -> IO ()
mutateConfig f = do
!cfg <- readConfig
let !newCfg = f cfg
in writeConfig newCfg
Bang模式用于禁用延迟评估:我需要在使用函数f
解析和修改旧配置之后将writeConfig称为。
但仍有问题:假设f
出错。在这种情况下,当发生错误时,writeConfig已经打开了要写入的文件(因为它是由惰性求值首先调用的),因此配置文件会丢失。
我试图从IO monads组成一个简单的逐步逻辑(为了防止数据丢失),像这样
!cfg <- readConfig
newCfg <- return $ f cfg
writeConfig newCfg
但这也不起作用(我有点期待)。
实现这一目标的正确方法是什么?