module Main where len1 [] = 0 len1 (_:xs) = 1 + len1 xs -- as per defn of length in standard prelude -- but gives stack overflow on big files (while length runs OK). len2 xs = let myLen [] n = n myLen (x:xs) n = myLen xs (1+n) -- n is lazy -- myLen (x:xs) n = myLen xs $! (1+n) -- n is strict in myLen xs 0 -- ^^stack o'flow on big files without strict "!" -- word-count, wc wc xs = -- I've probably got the "end of word" condition wrong below... let w [] nl nw nc = (nl, nw, nc) -- lines words chars w ('\n':xs) nl nw nc = ((w xs $! (nl+1)) $! (nw+1)) $! (nc+1) w (' ' :xs) nl nw nc = (w xs nl $! (nw+1)) $! (nc+1) w (_ :xs) nl nw nc = w xs nl nw $! (nc+1) in w xs 0 0 0 -- "!" on data dec's, "$!" for application, and "seq" effect strict evaluation. -- ---------------------------------------------------------------------------- fstLn = "file & strictness experiments, L.A., CSSE, Monash, .au, 12/12/2003" main = putStrLn fstLn >> putStrLn "Input file name: " >> getLine >>= readFile -- >>= \s -> putStrLn( show(length s) ++ " chars") -- >>= \s -> putStrLn( show(len1 s) ++ " chars") -- stack o'flow on big file -- >>= \s -> putStrLn( show(len2 s) ++ " chars") >>= \s -> putStrLn( show(wc s) ++ " lines, words, chars" ) -- ----------------------------------------------------------------------------