摆脱Haskell的IO()

时间:2014-05-28 11:20:33

标签: haskell serialization monads

我很简单的应用程序具有保存/加载其当前状态的功能。 保存功能如下所示:

doSave :: BoardType -> Field -> [Char] -> Bool 
doSave board player fileName = do
    let x = encodeFile fileName (board :: BoardType, player :: Field)
    True -- there will be exception handling 

我的加载功能:

doLoad :: [Char] -> IO (BoardType, Field)
doLoad fileName = decodeFile fileName :: IO (BoardType, Field)

还有我的问题,加载后,我IO (BoardType, Field)不适合我的程序和其他可能不接受IO参数的函数。如果我遵循此IO次升级,我的申请中会有所有IO - 是否有必要(或者 - 使用haskell语言正常)?

最后 - 有一种简单的方法可以摆脱这个IO吗?

2 个答案:

答案 0 :(得分:7)

需要一点时间来适应。

有些monad让你在完成一些工作后提取“内在价值”,但IO绝不会。

没有办法,例如返回系统时间可能是“纯粹的”,因此您使用它进行的任何计算都需要保留在IO中。

然而,这并不意味着您的大部分代码都存在于IO-land中。

main = do
  (bt, fld) <- doLoad "somefilename"
  let bResult = doSomethingPureWithBoard bt
  let fResult = doSomethingPureWithField fld
  let bt2     = updateBoard bt bResult fResult
  doSave "someFilename" bt2 fld                -- This should also be in IO

你总是可以从IO调用纯函数,而不是相反。当您处于IO功能时,<-会为您提供“未包装”的值。实际上它将结果作为参数传递给下一个“声明” - 谷歌围绕“脱糖做法”和类似的。

答案 1 :(得分:2)

  

是否有必要(或者 - 正常使用haskell语言)

您的应用程序通常会有一个IO操作的外包装,从main :: IO ()开始,并且重复限制的代码具有越来越少的权限,直到您只处理纯代码。