我正在学习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...
)
我的问题是:
答案 0 :(得分:6)
怎么样
cmpFiles a b = do
aContents <- readFile a
bContents <- readFile b
return (aContents == bContents)
答案 1 :(得分:0)
你甚至可以用它做一个单行:
cmpFiles a b = liftM2 (==) (readFile a) (readFile b)
这个实际上相当于Reid Barton的解决方案。如果您从hackage
中选择liftM2
的定义,那么等效不是狡猾的词
liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
并立即插入(==)
和readFile
。
懒惰是你在haskell的朋友。 The documentation of readFile表示输入是 lazily ,即仅按需读取。 ==
也很懒惰。因此,整个liftM22 ...
只读取文件,直到找到差异。