Difference between revisions of "Simple Unix tools"
Jump to navigation
Jump to search
DonStewart (talk | contribs) (link) |
DonStewart (talk | contribs) (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 |
+ | |||
+ | -- |
||
⚫ | |||
+ | -- |
||
+ | 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) |
+ | -- |
||
⚫ | |||
-- |
-- |
||
+ | 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_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 |
||
− | -- repeat the input file infinitely |
||
-- |
-- |
||
+ | 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) |
||
− | join = input $ (:[]) . concat |
||
+ | where f = reverse . dropWhile isSpace . reverse |
||
-- |
-- |
||
+ | -- delete leading and trailing whitespace |
||
− | -- Translate the letter 'e' to '*', like tr 'e' '*' (or y// in sed) |
||
-- |
-- |
||
− | + | 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' = '*' |
||
− | |||
⚫ | |||
-- |
-- |
||
− | -- |
+ | -- 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