Back Story: In an attempt to better understand Haskell and functional programming, I've given myself a few assignments. My first assignment is to make a program that can look through a data set (a set of numbers, words in a blog, etc), search for patterns or repetitions, group them, and report them.
Sounds easy enough. :)
Question: I'd like for the program to start by creating a list variable from the data in a text file. I'm familiar with the readFile function, but I was wondering if there was a more elegant way to input data.
For example, I'd like to allow the user to type something like this in the command line to load the program and the data set.
./haskellprogram textfile.txt
Is there a function that will allow this?
import System.Environment
main :: IO ()
main = do
args <- getArgs
-- args is a list of arguments
if null args
then putStrLn "usage: ./haskellprogram textfile.txt"
else do contents <- readFile $ head args
putStrLn $ doSomething contents
doSomething :: String -> String
doSomething = reverse
That should be enough to get you started. Now replace reverse
with something more valuable :)
Speaking of parsing some input data, you might consider breaking your data into lines
or words
using respective functions from Prelude.
You're looking for getArgs function.
Subtle Array, I can never resist mentioning my favorite when I was first learning Haskell, interact
:
module Main where
main = interact doSomething
doSomething :: String -> String
doSomething xs = reverse xs
you then use it as cat textfile.txt | ./haskellprogram | grep otto
or whatever. There is also a variant in Data.Text
which you might get to know, and a few others in other string-ish libraries.
Playing with the relatively new ReadArgs package:
{-# LANGUAGE ScopedTypeVariables #-}
import ReadArgs (readArgs)
main = do
(fname :: String, foo :: Int) <- readArgs
putStrLn fname
Testing...
$ runhaskell args.hs blahblah 3
blahblah
One irritation with readArgs
is that it doesn't work if you have only a single argument. Hmmm...
Once you have the desired file name as a String
, you can use readFile
as usual.