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" )
-- ----------------------------------------------------------------------------

