Inputting Data with Haskell

2019-06-22 17:12发布

问题:

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?

回答1:

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.



回答2:

You're looking for getArgs function.



回答3:

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.



回答4:

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.