I tried to write a program which takes filepaths as (command line) arguments and returns the first line of each file
main = getArgs >>= ( mapM_ ( \file -> ( openFile file ReadMode >>= ( (\handle -> hGetLine handle >>= print) >> hClose ) ) ) )
I know that this doesn't look very beautiful but I am just a beginner in Haskell. I did also avoid the do notation on purpose because I just don't feel very comfortable with her (yet).
So the Code above compiles and returns an error for invalid file paths, and nothing (i.e. especially not the first line of a file) for valid paths.
I must confess that I have pretty much no idea what I did wrong, but I made the following observation:
If I add the following to check which parts still get executed
main = getArgs >>= ( mapM_ ( \file -> ( openFile file ReadMode >>= ( (\handle -> hGetLine handle >>= print) >> (const $ putStr "Hello1") >> hClose >> (const $ putStr "Hello2") ) ) ) )
the program prints only the second "Hello", this reminded me of the type signature of (>>):
(>>) :: Monad m => m a -> m b -> m b
so taking into perspective that only something of the type of the second argument gets returned, maybe the first argument is just ignored?
But the first argument against this theory is that such a function would not seem to be very useful (at least not in the context of the IO Monad), and the second is that the program
main = (putStr "Hello" >> putStr "World" >> putStr "!")
returns 'HelloWorld!' as expected. Hence I must be completely on the wrong track, which is why I came here.
Thanks for your help!