⚠️Please use Hawk. While hwk is a hacky MVP to test how well Haskell works as text processing language, Hawk is a more mature tool. This repository is no longer maintained by Lukas Martinelli.
hwk tries to demonstrate how a modern Haskell based stream manipulation tool could look like.
It is similar to tools like awk or sed.
hwk allows compact command sequences that operate on a list of strings. Because Haskell is lazy and has a powerful arsenal of functions, there is no need to invent another DSL and hopefully
push people into using functional goodness.
hwk also provides a method to store small functions for
reuse in environment variables.
# prepend a string to each line seq 1 10 | hwk 'map ("number " ++)' # load the negative function into the current environment eval $(hwk env negative '(0 >)') # sum all negative numbers # the ints function transforms a list of strings into a list of ints seq -100 100 \ | hwk '\lines -> filter negative $ ints lines' \ | hwk '\lines -> sum $ ints lines' # get first two columns of tsv file # `cabal install split` to use the library for splitting lists cat data.tsv | | hwk '\lines -> map (take 2) $ map (splitOn "\t") lines'
The argument passed to
hwk must be a valid Haskell statement. It should always return a function that takes a list of strings and returns either a new list or a single element.
hwk env command loads the statement into the environment with the specified function name for later reuse.
git clone https://github.com/lukasmartinelli/hwk cd hwk stack build # or with cabal cabal install
hwkwill generate code and execute it under
hwkwill try to lookup functions in the passed environment variables.
hwktries to convert the different result types into a list of strings
hwkprovides additional functions that help with converting streams.
Supported return types
hwk statement can return the following types.
What happens under the Hood?
hwk code above can be translated directly into a valid Haskell program.
ints = map (\l -> read l :: Int) hwk = \lines -> filter (0 >) $ ints lines main = do contents <- getContents mapM_ putStrLn $ map (\r -> show r) $ hwk $ lines contents
hwk 'foldl (+) 0' command will translate to.
ints = map (\l -> read l :: Int) hwk = \lines -> foldl (+) 0 $ ints lines main = do contents <- getContents mapM_ putStrLn $ map (\r -> show r) $ hwk $ lines contents