Wheat Wizard
Wheat Wizard

Reputation: 4219

Conditional IO action

I am writing a program that should be able to read input either from the command line directly or from a file depending on what args are passed. For example. However I am having trouble making the IO event conditional. My first thought was to do:

import System.Environment

main :: IO ()
main = do
 cla <- getArgs
 let flags = parseFlags (filter isFlag cla) []
 let args  = filter (not.isFlag) cla
 input <- if (elem "e" flags) then (head args) else (readFile (head args))

However this doesn't work because (head args) is not a IO action. My next thought was to do:

import System.Environment

main :: IO ()
main = do
 cla <- getArgs
 let flags = parseFlags (filter isFlag cla) []
 let args  = filter (not.isFlag) cla
 file <- (readFile (head args))
 let input = if (elem "e" flags) then (head args) else (file)

But this will error if the input is not the name of a file. Is there a sensible way to do this? Am I approaching the problem incorrectly?

Upvotes: 0

Views: 219

Answers (2)

Carcigenicate
Carcigenicate

Reputation: 45691

You were trying to treat (head args) as though it was in the IO monad. Since it's just a raw value, you need to place it into the monad before it can be used as an IO action.

Just change (head args) to (return (head args)).

Upvotes: 4

ThreeFx
ThreeFx

Reputation: 7350

You can use return (head args) to lift a type to the IO monad.

Upvotes: 1

Related Questions