I'm learning Haskell and I need to compare two files. I did not find a function that does this, so I coded it myself. Below is the function I came up with.
cmpFiles :: FilePath -> FilePath -> IO Bool
cmpFiles a b = withBinaryFile a ReadMode $ \ha ->
withBinaryFile b ReadMode $ \hb ->
fix (\loop -> do
isEofA <- hIsEOF ha
isEofB <- hIsEOF hb
if | isEofA && isEofB -> return True -- both files reached EOF
| isEofA || isEofB -> return False -- only one reached EOF
| otherwise -> do -- read content
x <- hGet ha 4028 -- TODO: How to use a constant?
y <- hGet hb 4028 -- TODO: How to use a constant?
if x /= y
then return False -- different content
else loop -- same content, contunue...
)
My questions are:
- Is this code idiomatic? It looks very imperative rather than functional.
- Is this code efficient (Layz IO issues with big files, performance...)?
- Is there a more compact way to write it?