In order to facilitate reading a user-specified file while handling bad input, I've written this function:
readGetFile :: IO FilePath -> IO String
readGetFile getName =
catch (getName >>= readFile) (\e->do
let err = show (e :: IOException)
printf "Couldn't open file %v. Please enter a valid filename.\n" err
readGetFile getName >>= return)
This question is not about this function, and it is just used to illustrate a point.
If I call this function from GHCi, and eventually enter a good filename, it works as expected. However, if I try to terminate it early by hitting CTRL-C, strange things happen.
*Input> readGetFile getLine
{BadFile.jpeg
}Couldn't open file BadFile.jpeg: openFile: does not exist (No such file or directory). Please enter a valid filename.
{^C}Couldn't open file <stdin>: hGetLine: end of file. Please enter a valid filename.
{^C}CouInterrupted.
ldn't p*Input> e file <stdin>: hGetLine: end of file. Please enter a valid filename.
{^C}Couldn't open file <stdin>: hGetLine: end of file. Please enter a valid filename.
*Input> {
}Couldn't open file : openFile: does not exist (No such file or directory). Please enter a valid filename.
Note that text in {}
is entered by me (and I did not type {}
). {^C}
is me just hitting CTRL-C.
Obviously, the recursion is continuing to run and read from stdin, even as GHCi tries to resume running.
How can I terminate this loop from within GHCi?
Note: I have done hSetBuffering stdout NoBuffering
. This question is not about the implementation of readGetFile
and an answer must answer the bolded question above. An answer may provide a better way of implementing readGetFile
in addition if the answer provides reasoning for why it is nicer in respect to keyboard interrupts while still achieving the desired goal.
This apparently only occurs on Windows. I am on Windows running a default installation of Haskell Platform Core.