@@ -397,64 +397,103 @@ powerful ways of composing and applying them.
398## File IO
398## File IO
400−The following code snippet implements some common Unix command line utilities
400+The following code snippets implement some common Unix command line utilities
401−using streamly. To get an idea about IO streaming performance, you can
401+using streamly. You can compile these with `ghc -O2
402−benchmark these against the regular unix utilities using the `time` command.
402+-fspec-constr-recursive=10` and compare the performance with regular GNU
403−Make sure to use a big enough input file and compile with
403+coreutils available on your system. Source file
404−`ghc -O2 -fspec-constr-recursive=10` when benchmarking. Use `+RTS -s` flags on
404+[HandleIO.hs](https://github.com/composewell/streamly/tree/master/examples/HandleIO.hs)
405−the executable to check the space usage, look for `maximum residency` in the
405+in the examples directory includes these examples.
408−Note that `grep -c` counts the number of lines where the pattern occurs whereas
409−the snippet below counts the total number of occurrences of the pattern,
410−therefore, the output may differ.
412``` haskell
407``` haskell
413import qualified Streamly.Prelude as S
410import qualified Streamly.Prelude as S
414import qualified Streamly.Fold as FL
411import qualified Streamly.Fold as FL
415import qualified Streamly.Mem.Array as A
412import qualified Streamly.Mem.Array as A
416−import qualified Streamly.FileSystem.File as File
413+import qualified Streamly.FileSystem.Handle as FH
414+import qualified System.IO as FH
418import Data.Char (ord)
416import Data.Char (ord)
419import System.Environment (getArgs)
417import System.Environment (getArgs)
420import System.IO (openFile, IOMode(..), stdout)
418import System.IO (openFile, IOMode(..), stdout)
421+ (name : _) <- getArgs
422+ src <- openFile name ReadMode
426+ (sname : dname : _) <- getArgs
427+ src <- openFile sname ReadMode
428+ dst <- openFile dname WriteMode
422−cat src = File.writeArrays stdout $ File.readArraysUpto (256*1024) src
435+cat = FH.writeArrays stdout . FH.readArraysOfUpto (256*1024)
423−cp src dst = File.writeArrays dst $ File.readArraysUpto (256*1024) src
442+cp src dst = FH.writeArrays dst $ FH.readArraysOfUpto (256*1024) src
424−wcl src = print =<<
443+main = withArg2 cp
425− ( S.length
450+ S.length
426− $ FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.drain
451+ . FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.drain
427− $ File.read src)
452+ . FH.read
428−grepc pat src = print . (subtract 1) =<<
453+main = withArg wcl >>= print
458+Note that `grep -c` counts the number of lines where the pattern occurs whereas
459+the snippet below counts the total number of occurrences of the pattern,
460+therefore, the output may differ.
429− ( S.length
464+ S.length
430− $ FL.splitOn (A.fromList (map (fromIntegral . ord) pat)) FL.drain
465+ . FL.splitOn (A.fromList (map (fromIntegral . ord) pat)) FL.drain
431− $ File.read src)
466+ . FH.read
467+main = withArg (grepc "pattern") >>= print . subtract 1
470+### Average Line Length
432−avgll src = print =<<
473+avgll =
433− ( FL.foldl' avg
474+ FL.foldl' avg
434− $ FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
475+ . FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
435− $ File.read src)
476+ . FH.read
436− where avg = (/) <$> toDouble FL.sum <*> toDouble FL.length
478+ where avg = (/) <$> toDouble FL.sum <*> toDouble FL.length
437 toDouble = fmap (fromIntegral :: Int -> Double)
479 toDouble = fmap (fromIntegral :: Int -> Double)
438−llhisto src = print =<<
439− ( FL.foldl' (FL.classify FL.length)
441− $ FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
444− bucket n = let i = n `div` 10 in if i > 9 then (9,n) else (i,n)
446−main = do
481+main = withArg avgll >>= print
447− name <- fmap head getArgs
482+```
448− src <- openFile name ReadMode
449− -- cat src -- Unix cat program
450− -- wcl src -- Unix wc -l program
451− -- grepc "aaaa" src -- Unix grep -c program
453− -- dst <- openFile "dst.txt" WriteMode
484+### Line Length Histogram
454− -- cp src dst -- Unix cp program
485+
488+ FL.foldl' (FL.classify FL.length)
490+ . FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
494+ bucket n = let i = n `div` 10 in if i > 9 then (9,n) else (i,n)
456− -- avgll src -- get average line length
496+main = withArg llhisto >>= print
457− llhisto src -- get line length histogram
460## Socket IO
499## Socket IO