For some file operation, I need to check if the file exists, if it has been modified, and only then perform some operation on it. My newbie Haskell code looks as follows (simplified):
someFileOp ::FileContents -> FilePath -> IO (FileOpResult)
someFileOp contents absFilePath = do
fileExists <- DIR.doesFileExist absFilePath
if fileExists
then do
isMod <- isModified contents absFilePath
if isMod
then return FileModified
else return $ doSomethingWithFile
else return FileNotFound
It does work. However, the nested if-expressions look wrong to me - not FP-like. What would be an idiomatic way to check several Boolean conditions in IO and then take some action depending on their result?
The code you posted looks fine to me. Another possibility would be to act in a short-circuiting monad like ExceptT Err IO
.
data Err = FileNotFound | FileModified
getFileContents :: FilePath -> ExceptT Err IO FileContents
getFileContents fp = do
exists <- doesFileExist fp
if exists then {- ... -} else throwError FileNotFound
someFileOp :: FileContents -> FilePath -> ExceptT Err IO FileOpResult
someFileOp fc fp = do
fc' <- getFileContents fp
when (fc /= fc') (throwError FileModified)
doSomethingWithFile