Как встроить Haskell в пакетный файл (hash-bang runhaskell для Windows)?

В UNIX-подобной системе с установленным GHC я могу создать файл со следующим содержимым

#!/usr/bin/env runhaskell
main = putStrLn "Hello, I am a UNIX script file."

Сделайте файл исполняемым, и это выполнит данный код на Haskell.

Как мне сделать эквивалент в Windows .bat файле?

Предпочтительно, чтобы не создавались дополнительные файлы, не задавались переменные среды, это также работает, если доступ к пакетному файлу осуществляется с использованием пути UNC или пути, содержащего пробелы, пространство имен Haskell не загрязнено, и в случае, если код Haskell содержит разумное поведение, получается разумное поведение. ошибки.

2 ответа

Решение

После долгих проб и ошибок это оказывается возможным. Я разработал следующее:

@(set /p =-- < nul & type "%~f0") | runhaskell & exit /b
main = putStrLn "Hello, I am a Windows batch file."

Единственным недостатком этого механизма является то, что сообщения об ошибках содержат имя временного файла, созданного (что называется) runhaskell,

Вот полное объяснение того, как это работает:

  • set /p =-- < nul выходы -- (и два несоответствующих пробела), за которыми не следует перевод строки. Это работает так:
    • set /p ANSWER=Please enter answer: печать Please enter answer: без новой строки, ожидает ввода пользователя и помещает его в переменную окружения ANSWER,
    • < nul действует так, как будто пользователь ничего не вводил.
    • В качестве (недокументированного?) Особого случая имя переменной среды может быть опущено, и тогда переменная среды не устанавливается.
  • "%~f0" имя текущего пакетного файла.
  • Следовательно set /p =-- < nul & type "%~f0" выводит текущий пакетный файл, но с закомментированной первой строкой (когда интерпретируется как код на Haskell).
  • Мы доставим это в runhaskell, который (недокументировано?) интерпретирует свой stdin как не буквальный (!) код на Haskell.
    • Как и в версии UNIX в вопросе, это предполагает, что runhaskell на текущий PATH,
  • В заключение, exit удостоверится, что интерпретатор командного файла Windows не видит ничего после первой строки, и exit /b гарантирует, что мы выйдем только из этого скрипта, а не из окружения cmd.exe ракушка.
  • И ведущий @ следит за тем, чтобы все это echoEd при запуске этого скрипта.

(Я не нашел способа сделать то же самое для грамотного кода на Haskell; но мне это сейчас не нужно.)

Просто создайте под своим PATH

C:\my-tools-path>copy con --.bat
runhaskell %1
^Z

Чтобы создать свою автоматически исполняемую программу на Haskell, напишите что-то вроде

-- "%~f0"
main = putStrLn "Merry Christmas!"

Нет ошибок, нет временных файлов,...

;)

(Вы можете добавить свою программу, изменяя аргументы

runhaskell %1 %2 ...

а также

-- "%~f0" %1 %2 ...

)

Другие вопросы по тегам