After much trial and error, this turns out to be possible. I have designed the following:
@(set /p =-- < nul & type "%~f0") | runhaskell & exit /b
main = putStrLn "Hello, I am a Windows batch file."
The only disadvantage of this mechanism is that error messages contain the name of a temp file created by (something called by) runhaskell
.
Here is a full explanation of how this works:
set /p =-- < nul
outputs--
(and two irrelevant spaces) not followed by a newline. This works like this:set /p ANSWER=Please enter answer:
printsPlease enter answer:
without a newline, waits for user input, and puts that in environment variableANSWER
.< nul
acts as if the user did not enter anything.- As an (undocumented?) special case, the environment variable name can be left out, and then no environment variable is set.
"%~f0"
is the name of the current batch file.- Therefore
set /p =-- < nul & type "%~f0"
outputs the current batch file, but with the first line commented out (when interpreted as Haskell code). - We pipe this into
runhaskell
, which (undocumentedly?) interprets its stdin as non-literal (!) Haskell code.- Like in the UNIX version in the question, this assumes that
runhaskell
is on the currentPATH
.
- Like in the UNIX version in the question, this assumes that
- Finally,
exit
makes sure that everything after the first line is not seen by the Windows batch file interpreter, andexit /b
makes sure that we only exit this script, not any surroundingcmd.exe
shell. - And the leading
@
makes sure that all this gibberish is notecho
ed when running this script.
(I have not found a way to do the same for literate Haskell code; but I don't have a need for that currently.)