@@ -397,64 +397,103 @@ powerful ways of composing and applying them.
397397
398398## File IO
399399
400−The following code snippet implements some common Unix command line utilities
401−using streamly. To get an idea about IO streaming performance, you can
402−benchmark these against the regular unix utilities using the `time` command.
403−Make sure to use a big enough input file and compile with
404−`ghc -O2 -fspec-constr-recursive=10` when benchmarking. Use `+RTS -s` flags on
405−the executable to check the space usage, look for `maximum residency` in the
406−output.
407−
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.
400+The following code snippets implement some common Unix command line utilities
401+using streamly. You can compile these with `ghc -O2
402+-fspec-constr-recursive=10` and compare the performance with regular GNU
403+coreutils available on your system. Source file
404+[HandleIO.hs](https://github.com/composewell/streamly/tree/master/examples/HandleIO.hs)
405+in the examples directory includes these examples.
411406
412407``` haskell
408+module Main where
409+
413410import qualified Streamly.Prelude as S
414411import qualified Streamly.Fold as FL
415412import 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
417415
418416import Data.Char (ord)
419417import System.Environment (getArgs)
420418import System.IO (openFile, IOMode(..), stdout)
421419
422−cat src = File.writeArrays stdout $ File.readArraysUpto (256*1024) src
423−cp src dst = File.writeArrays dst $ File.readArraysUpto (256*1024) src
424−wcl src = print =<<
425− ( S.length
426− $ FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.drain
427− $ File.read src)
428−grepc pat src = print . (subtract 1) =<<
429− ( S.length
430− $ FL.splitOn (A.fromList (map (fromIntegral . ord) pat)) FL.drain
431− $ File.read src)
432−avgll src = print =<<
433− ( FL.foldl' avg
434− $ FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
435− $ File.read src)
436− where avg = (/) <$> toDouble FL.sum <*> toDouble FL.length
420+withArg f = do
421+ (name : _) <- getArgs
422+ src <- openFile name ReadMode
423+ f src
424+
425+withArg2 f = do
426+ (sname : dname : _) <- getArgs
427+ src <- openFile sname ReadMode
428+ dst <- openFile dname WriteMode
429+ f src dst
430+```
431+
432+### cat
433+
434+``` haskell
435+cat = FH.writeArrays stdout . FH.readArraysOfUpto (256*1024)
436+main = withArg cat
437+```
438+
439+### cp
440+
441+``` haskell
442+cp src dst = FH.writeArrays dst $ FH.readArraysOfUpto (256*1024) src
443+main = withArg2 cp
444+```
445+
446+### wc -l
447+
448+``` haskell
449+wcl =
450+ S.length
451+ . FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.drain
452+ . FH.read
453+main = withArg wcl >>= print
454+```
455+
456+### grep -c
457+
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.
461+
462+``` haskell
463+grepc pat =
464+ S.length
465+ . FL.splitOn (A.fromList (map (fromIntegral . ord) pat)) FL.drain
466+ . FH.read
467+main = withArg (grepc "pattern") >>= print . subtract 1
468+```
469+
470+### Average Line Length
471+
472+``` haskell
473+avgll =
474+ FL.foldl' avg
475+ . FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
476+ . FH.read
477+
478+ where avg = (/) <$> toDouble FL.sum <*> toDouble FL.length
437479 toDouble = fmap (fromIntegral :: Int -> Double)
438−llhisto src = print =<<
439− ( FL.foldl' (FL.classify FL.length)
440− $ S.map bucket
441− $ FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
442− $ File.read src)
443− where
444− bucket n = let i = n `div` 10 in if i > 9 then (9,n) else (i,n)
445480
446−main = do
447− name <- fmap head getArgs
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
481+main = withArg avgll >>= print
482+```
452483
453− -- dst <- openFile "dst.txt" WriteMode
454− -- cp src dst -- Unix cp program
484+### Line Length Histogram
485+
486+``` haskell
487+llhisto =
488+ FL.foldl' (FL.classify FL.length)
489+ . S.map bucket
490+ . FL.splitSuffixBy (== fromIntegral (ord '\n')) FL.length
491+ . FH.read
492+
493+ where
494+ bucket n = let i = n `div` 10 in if i > 9 then (9,n) else (i,n)
455495
456− -- avgll src -- get average line length
457− llhisto src -- get line length histogram
496+main = withArg llhisto >>= print
458497```
459498
460499## Socket IO