Simple Unix commandline tools written in Haskell.
This is intended as a beginner’s tutorial for learning Haskell from a “Let’s just solve things already!” point of view. The examples should help give a flavor of the beauty and expressiveness of Haskell programming.
These functions can be executed as one liners from a shell. For example, to use the Haskell version of ‘wc’:
$ cat file.txt | ghc -e 'wc_l' UnixTools.hs
Or, one could define ‘main’ to be a chosen tool/function (add a line to the effect that “main = wc_l”) and then compile the tool with
$ ghc --make UnixTools.hs
import Control.Monad.Instances import Data.List import Data.Char import Data.Maybe import Text.Printf import System.Environment -- First, two helpers io f = interact (unlines . f . lines) showln = (++ "n") . show -- remove duplicate lines from a file (like uniq) uniq = nub -- repeat the input file infinitely rpt = cycle -- Return the head -10 line of a file take' = take 10 -- Remove the first 10 lines of a file drop' = drop 10 -- Return the head -1 line of a file head' = head -- Return the tail -1 line of a file tail' = last -- return the last ten lines of a file tail10 = drop =<< subtract 10 . length -- Reverse lines in a file (tac) tac = reverse -- Reverse characters on each line (rev) rev = map reverse -- Reverse words on each line rev_w = map (unwords . reverse . words) -- Count number of characters in a file (like wc -c) wc_c = showln . length -- Count number of lines in a file, like wc -l wc_l = showln . length . lines -- Count number of words in a file (like wc -w) wc_w = showln . length . words -- double space a file space = intersperse "" -- undo double space unspace = filter (not.null) -- remove the first occurrence of the line "str" remove = delete -- make a string all upper case upper = map toUpper -- remove leading space from each line clean = map (dropWhile isSpace) -- remove trailing whitespace clean' = map (reverse . dropWhile isSpace . reverse) -- delete leading and trailing whitespace clean'' = map (f . f) where f = reverse . dropWhile isSpace -- insert blank space at beginning of each line blank = map (s ++) where s = replicate 8 ' ' -- join lines of a file join = return . concat -- Translate the letter 'e' to '*', like tr 'e' '*' (or y// in sed) tr a b = interact (map f) where f c = if c == a then b else c -- Delete characters from a string. tr_d a = tr a ' ' -- grep lines matching "^foo" from a file grep = filter (isPrefixOf "foo") -- grep lines that don't match "^foo" (grep -v) grep_v = filter (not . isPrefixOf "foo") -- number each line of a file num = zipWith (printf "%3d %s") [(1::Int)..] -- Compute a simple cksum of a file cksum = foldl' k 5381 where k h c = h * 33 + ord c