Sunday, June 22, 2008

the rosetta code?

or just plain creepy?  [source]

(actually, there's a bunch more that's fascinating me too...)

-- Some unix-like tools written in simple, clean Haskell


-- Author: Don Stewart, 2006, http://www.cse.unsw.edu.au/~dons
-- Free for any use.
--

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

1 comments:

kruhft said...

plus, '.' is '|' and they flow BACKWARDS

IIRC from trying to wrap my head around the beast that is haskell.

of course, I do also recall that you could completely redo the langugage, since most of it was written in the prelude.

sort of like prolog, but spineless and tagless...

~/.history