我正在学习Haskell,需要比较两个文件。我没有找到可以做到这一点的函数,所以我自己编写了一个。以下是我想出来的函数。
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...
)
我的问题是:
- 这段代码是否符合惯用法? 它看起来非常命令式而不是函数式。
- 这段代码是否高效(大文件的Layz IO问题,性能...)?
- 有没有更紧凑的编写方式?
withBinaryFile
和惰性IO不兼容。 - n. m.fix
很少必要或有助于编写清晰的代码;显式递归通常更好。 - dfeuer