我很简单的应用程序具有保存/加载其当前状态的功能。 保存功能如下所示:
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
吗?
答案 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 ()
开始,并且重复限制的代码具有越来越少的权限,直到您只处理纯代码。