Simple Unix tools
From HaskellWiki
(Difference between revisions)
(link) |
(update) |
||
| Line 9: | Line 9: | ||
-- | -- | ||
-- Some unix-like tools written in simple, clean Haskell | -- Some unix-like tools written in simple, clean Haskell | ||
| + | -- | ||
-- | -- | ||
| Line 17: | Line 18: | ||
-- | -- | ||
| - | -- First, | + | -- First, two helpers |
-- | -- | ||
| - | + | io f = interact (unlines . f . lines) | |
| + | showln = (++ "\n") . show | ||
-- | -- | ||
| Line 29: | Line 31: | ||
-- Sort a file | -- Sort a file | ||
-- | -- | ||
| - | sort' = | + | sort' = io sort |
| + | |||
| + | -- | ||
| + | -- remove duplicate lines from a file (like uniq) | ||
| + | -- | ||
| + | uniq = io nub | ||
-- | -- | ||
| - | -- | + | -- repeat the input file infintely |
-- | -- | ||
| - | + | rpt = interact cycle | |
-- | -- | ||
-- Return the head -10 line of a file | -- Return the head -10 line of a file | ||
-- | -- | ||
| - | + | take' = io (take 10) | |
-- | -- | ||
-- Remove the first 10 lines of a file | -- Remove the first 10 lines of a file | ||
-- | -- | ||
| - | drop' = | + | drop' = io (drop 10) |
| + | |||
| + | -- | ||
| + | -- Return the head -1 line of a file | ||
| + | -- | ||
| + | head' = io (return . head) | ||
-- | -- | ||
-- Return the tail -1 line of a file | -- Return the tail -1 line of a file | ||
-- | -- | ||
| - | tail' = | + | tail' = io (return . last) |
| + | -- | ||
| + | -- Reverse lines in a file (tac) | ||
-- | -- | ||
| - | -- | + | tac = io reverse |
| + | |||
| + | -- | ||
| + | -- Reverse characters on each line (rev) | ||
-- | -- | ||
| - | + | rev = io (map reverse) | |
| + | |||
| + | -- | ||
| + | -- Reverse words on each line | ||
| + | -- | ||
| + | revw = io $ map (unwords. reverse . words) | ||
| + | |||
| + | -- | ||
| + | -- Count number of characters in a file (like wc -c) | ||
| + | -- | ||
| + | wc_c = interact (showln . length) | ||
| + | |||
| + | -- | ||
| + | -- Count number of lines in a file, like wc -l | ||
| + | -- | ||
| + | wc_l = interact (showln . length . lines) | ||
| + | |||
| + | -- | ||
| + | -- Count number of words in a file (like wc -w) | ||
| + | -- | ||
| + | wc_w = interact (showln . length . words) | ||
-- | -- | ||
-- double space a file | -- double space a file | ||
-- | -- | ||
| - | space = | + | space = io (intersperse "") |
-- | -- | ||
| - | -- | + | -- undo double space |
-- | -- | ||
| - | + | unspace = io $ filter (not.null) | |
-- | -- | ||
-- remove the first occurence of the line "str" | -- remove the first occurence of the line "str" | ||
-- | -- | ||
| - | remove = | + | remove = io (delete "str") |
-- | -- | ||
-- make a file all upper case | -- make a file all upper case | ||
-- | -- | ||
| - | upper = interact | + | upper = interact (map toUpper) |
-- | -- | ||
-- remove leading space from each line | -- remove leading space from each line | ||
-- | -- | ||
| - | clean = | + | clean = io $ map (dropWhile isSpace) |
-- | -- | ||
| - | -- | + | -- remove trailing whitespace |
-- | -- | ||
| - | + | clean' = io (map f) | |
| + | where f = reverse . dropWhile isSpace . reverse | ||
-- | -- | ||
| - | -- | + | -- delete leading and trailing whitespace |
-- | -- | ||
| - | + | clean'' = io $ map (f . f) | |
| - | where f | + | where f = reverse . dropWhile isSpace |
| - | + | ||
-- | -- | ||
| - | -- | + | -- insert blank space at beginning of each line |
-- | -- | ||
| - | + | blank = io $ map (s ++) | |
| + | where s = replicate 8 ' ' | ||
-- | -- | ||
| - | -- | + | -- join lines of a file |
-- | -- | ||
| - | + | join = io (return . concat) | |
-- | -- | ||
| - | -- | + | -- Translate the letter 'e' to '*', like tr 'e' '*' (or y// in sed) |
-- | -- | ||
| - | + | y = interact (map f) | |
| - | + | where f 'e' = '*' | |
| + | f c = c | ||
-- | -- | ||
| - | -- | + | -- Filter the letter 'e' from a file, like tr -d 'e' |
-- | -- | ||
| - | + | tr = interact $ filter (/= 'e') | |
-- | -- | ||
-- grep lines matching "^foo" from a file | -- grep lines matching "^foo" from a file | ||
-- | -- | ||
| - | grep = | + | grep = io $ filter (isPrefixOf "foo") |
-- | -- | ||
-- grep lines that don't match "^foo" (grep -v) | -- grep lines that don't match "^foo" (grep -v) | ||
-- | -- | ||
| - | grep_v = | + | grep_v = io $ filter (not . isPrefixOf "foo") |
-- | -- | ||
-- number each line of a file | -- number each line of a file | ||
-- | -- | ||
| - | num = | + | num = io $ zipWith (printf "%3d %s") [(1::Int)..] |
-- | -- | ||
| - | -- Compute a simple | + | -- Compute a simple cksum of a file |
-- | -- | ||
| - | cksum = interact $ | + | cksum = interact $ showln . foldl' k 5381 |
| - | where k h c = h * 33 + | + | where k h c = h * 33 + ord c |
| + | |||
</haskell> | </haskell> | ||
| + | |||
'''Where to now?''' | '''Where to now?''' | ||
Revision as of 13:54, 23 September 2006
Simple unix tools written in Haskell.
This is intended as a beginners tutorial for learning Haskell from a "Lets just solve things already!" point of view. The examples should help give a flavour of the beauty and expressiveness of Haskell programming.
-- -- Some unix-like tools written in simple, clean Haskell -- -- import Data.List import Data.Char import System.IO import Text.Printf -- -- First, two helpers -- io f = interact (unlines . f . lines) showln = (++ "\n") . show -- -- The 'cat' program -- cat = interact id -- -- Sort a file -- sort' = io sort -- -- remove duplicate lines from a file (like uniq) -- uniq = io nub -- -- repeat the input file infintely -- rpt = interact cycle -- -- Return the head -10 line of a file -- take' = io (take 10) -- -- Remove the first 10 lines of a file -- drop' = io (drop 10) -- -- Return the head -1 line of a file -- head' = io (return . head) -- -- Return the tail -1 line of a file -- tail' = io (return . last) -- -- Reverse lines in a file (tac) -- tac = io reverse -- -- Reverse characters on each line (rev) -- rev = io (map reverse) -- -- Reverse words on each line -- revw = io $ map (unwords. reverse . words) -- -- Count number of characters in a file (like wc -c) -- wc_c = interact (showln . length) -- -- Count number of lines in a file, like wc -l -- wc_l = interact (showln . length . lines) -- -- Count number of words in a file (like wc -w) -- wc_w = interact (showln . length . words) -- -- double space a file -- space = io (intersperse "") -- -- undo double space -- unspace = io $ filter (not.null) -- -- remove the first occurence of the line "str" -- remove = io (delete "str") -- -- make a file all upper case -- upper = interact (map toUpper) -- -- remove leading space from each line -- clean = io $ map (dropWhile isSpace) -- -- remove trailing whitespace -- clean' = io (map f) where f = reverse . dropWhile isSpace . reverse -- -- delete leading and trailing whitespace -- clean'' = io $ map (f . f) where f = reverse . dropWhile isSpace -- -- insert blank space at beginning of each line -- blank = io $ map (s ++) where s = replicate 8 ' ' -- -- join lines of a file -- join = io (return . concat) -- -- Translate the letter 'e' to '*', like tr 'e' '*' (or y// in sed) -- y = interact (map f) where f 'e' = '*' f c = c -- -- Filter the letter 'e' from a file, like tr -d 'e' -- tr = interact $ filter (/= 'e') -- -- grep lines matching "^foo" from a file -- grep = io $ filter (isPrefixOf "foo") -- -- grep lines that don't match "^foo" (grep -v) -- grep_v = io $ filter (not . isPrefixOf "foo") -- -- number each line of a file -- num = io $ zipWith (printf "%3d %s") [(1::Int)..] -- -- Compute a simple cksum of a file -- cksum = interact $ showln . foldl' k 5381 where k h c = h * 33 + ord c
Where to now?
- Haskell.org
- The Haskell standard list library, with docs
- Alternative implementations of the wc program
- Learn how to test Haskell code
- More Haskell code
- Haskell for shell scripting
- Export list functions to the shell with h4sh
