I am designing the IO for a program I have written in Haskell. I would like to be able to read some arguments from file using -f
or from the command line by default. The command line arguments get split up into convenient chunks meaning I do not need to parse them. However this does not happen when reading from file. So I wrote a simple little parser to do what I wanted.
parseFile :: String -> [String]
parseFile [] = [""]
parseFile ('"':xs) = parseString xs '"'
parseFile ('\'':xs) = parseString xs '\''
parseFile (' ':xs) = "":parseFile xs
parseFile ('\t':xs) = "":parseFile xs
parseFile ('\n':xs) = "":parseFile xs
parseFile (s:xs) = (\(a:xa)->(a++[s]):xa)$ parseFile xs
parseString :: String -> Char -> [String]
parseString (s:xs) a
| s == a = "":parseFile xs
| otherwise = (\(a:xa)->(a++[s]):xa)$ parseString xs a
I thought this would be pretty simple I would do something like
let myInput = if (flagDetected) then (parseFile $ readFile $ last args) else (args)
However the result of readFile
is an IO action and not a string thus I cannot parse it. I've tried a number of configurations all which have fails, mostly for typing reasons. I've tried assigning the results before parsing, which resulted in a type mismatch between args
which is a [[Char]]
( it is the result of using getArgs
from the System.Environment
module) and the result of readFile
which is still an IO String.
I tried wrapping args
with a return
which of course doesn't fix this problem because of a type mismatch. I'm really at a loss of ideas now. I feel like this is probably a problem with the way I am thinking about the issue.
How can I get the behavior I desire?
Here's a related question I asked earlier. The root of the problem is the same but the answers on the last one were far to specific to help me here. It seems this is a frequent problem for me.