Ich lerne Haskell und ich muss zwei Dateien vergleichen. Ich habe keine Funktion gefunden, die das tut, also habe ich es selbst codiert. Unten ist die Funktion, die ich mir ausgedacht habe.Wie zwei Dateien in Haskell zu vergleichen
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...
)
Meine Fragen sind:
- Ist dieser Code idiomatische? Es sieht eher zwingend als funktional aus.
- Ist dieser Code effizient (Layz IO Probleme mit großen Dateien, Leistung ...)?
- Gibt es eine kompaktere Art, es zu schreiben?
Es ist nicht klar, ob Sie faule oder strikte Bytestrings verwenden (zeigen Sie immer Ihre Importe!) Ich denke, Ihr Programm wird nur mit strikten Bytestrings funktionieren, 'withBinaryFile' und Lazy IO mischen sich nicht gut. –
Ihre Funktion ist zu groß. Ein einfacher Schritt wäre, eine separate Funktion zu schreiben, die zwei * Handles * benötigt. 'fix' ist selten notwendig oder hilfreich zum Schreiben von klarem Code; explizite Rekursion ist normalerweise besser. – dfeuer