Working character by character in Haskell

Andre W B Furtado awfurtado@uol.com.br
Thu, 18 Oct 2001 18:34:40 -0300


I'm trying to create a fast program in Haskell that reads the content of a
file, do some stuff with its characters (one by one) an then save the final
result (the modified characters) in another file. The fastest program I've
developed so far is:

main :: IO ()
main = do
 bmFile <- openFileEx "in.txt" (BinaryMode ReadMode)
 bmString <- hGetContents bmFile
 str <- copyFile bmString []
 writeFile "out.txt" str
 hClose bmFile

copyFile :: String -> String -> IO String
copyFile [] s = return (reverse s)
copyFile (a:as) s = copyFile as ( (doSomeStuffWith a):s)

What I can't understand is why a similar program, written in C, is much
faster than the Haskell program. Here you have the C program:

void main()
{
 FILE *in, *out;
 char ch;

 in = fopen("in.txt","rb");
 out = fopen("out.txt","wb");

 while ( (ch=getc(in)) != EOF)
  putc(doSomeStuffWith(ch),out);
 fclose(out);
 fclose(in);
}

For example, suppose function doSomeStuffWith returns its own parameter.
Using a 1.5MB file in this case, the Haskell program ends in almost 5
seconds, while the C program ends in less than 0.5 seconds... Is my Haskell
program too bad implemented? (I'm using GHC 4.08-1 under a Windows 98
platform.)

Thanks,
-- Andre