Getting rid of Haskell's IO ( )

haskell, monads, serialization

Solution

It takes a little while to get used to.

Some monads let you extract the "inner value" after some work, but IO never does.

There is no way that e.g. returning the system time can ever be "pure" so any calculations you make with it need to remain wrapped in IO.

However, that doesn't mean most of your code lives in 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

You can always call pure functions from IO, just not the other way around. The `<-` gives you the "unwrapped" values while you are in an IO function. Actually it's passing the results as parameters to the next "statement" - google around "de-sugaring do notation" and similar.

Problem

I am wiriting simple application which has functionality of saving/loading its current state. Save function looks as below: ``` doSave :: BoardType -> Field -> [Char] -> Bool doSave board player fileName = do let x = encodeFile fileName (board :: BoardType, player :: Field) True -- there will be exception handling ``` And my load function: ``` doLoad :: [Char] -> IO (BoardType, Field) doLoad fileName = decodeFile fileName :: IO (BoardType, Field) ``` And there's my problem, after loading, I have `IO (BoardType, Field)` which does not fit my program and other functions which probably should not accept `IO` parameters. If I have followed this `IO` escalation, there would be all `IO`s in my application - is it necessary (or - normal in haskell language)? And finally - is there a simple way I can get rid of this `IO`?

Original source