Reputation: 2911
I currently have this code which will perform the main'
function on each of the filenames in the list files
.
Ideally I have been trying to combine main
and main'
but I haven't made much progress. Is there a better way to simplify this or will I need to keep them separate?
{- Start here -}
main :: IO [()]
main = do
files <- getArgs
mapM main' files
{- Main's helper function -}
main' :: FilePath -> IO ()
main' file = do
contents <- readFile file
case (runParser parser 0 file $ lexer contents) of Left err -> print err
Right xs -> putStr xs
Thanks!
Edit: As most of you are suggesting; I was trying a lambda abstraction for this but wasn't getting it right. - Should've specified this above. With the examples I see this better.
Upvotes: 1
Views: 152
Reputation: 24832
The Control.Monad
library defines the function forM
which is mapM
is reverse arguments. That makes it easier to use in your situation, i.e.
main :: IO ()
main = do
files <- getArgs
forM_ files $ \file -> do
contents <- readFile file
case (runParser f 0 file $ lexer contents) of
Left err -> print err
Right xs -> putStr xs
The version with the underscore at the end of the name is used when you are not interested in the resulting list (like in this case), so main
can simply have the type IO ()
. (mapM
has a similar variant called mapM_
).
Upvotes: 6
Reputation: 38758
You can use forM
, which equals flip mapM
, i.e. mapM
with its arguments flipped, like this:
forM_ files $ \file -> do
contents <- readFile file
...
Also notice that I used forM_
instead of forM
. This is more efficient when you are not interested in the result of the computation.
Upvotes: 5