我该如何在ghci中加载没有.haskell扩展名的runhaskell脚本?

8

我已经用Haskell编写了一个名为testscript的脚本,并包含以下代码:

#!/usr/bin/env runhaskell

main = putStrLn "hello"

将脚本设置为可执行后,可以使用./testscript运行它。但是,当我尝试使用ghci(即使用:l testscript)加载脚本时,会出现错误。

target `testscript' is not a module name or a source file

如果我将testscript重命名为testscript.hs,然后再次尝试用ghci加载,我会收到错误提示。
testscript.hs:1:0:  error: invalid preprocessing directive #!
phase `C pre-processor' failed (exitcode = 1)

如果我删除shebang行,它能正常工作。但是每次想在ghci中尝试脚本时都必须添加.hs扩展名,删除顶部行,然后删除.hs扩展名并添加shebang行,这很繁琐(每次想要对其进行更改时都很常见)。有更简单的方法吗?
我正在使用Mac OS X 10.6.8下的ghc版本7.0.3。

至少在Linux上,我没有关于#!的最后一个错误;我相信如果它是第一行,那么ghci应该将其视为注释。 - ivanm
1个回答

12

你可以使用 -x 选项告诉 GHCi(或 GHC)将所有后续文件视为具有指定扩展名。

在 GHCi 中似乎没有任何方法可以指定此选项(用于与 :load 一起使用),但是如果您需要这样做,可以使用以下解决方法:创建一个带有 .hs 扩展名的符号链接并加载它。

导致 shebang 行出现第二个问题的原因是某种原因运行了 C 预处理器对源文件进行预处理(我的 Ubuntu 上旧版的 GHC 安装不会这样做)。可以通过使用 -XNoCPP 选项来禁用这个问题。

因此,在您的情况下,从命令行运行以下命令应该可以解决问题:

ghci -x hs -XNoCPP testscript

1
谢谢,可以了。之所以 C 预处理器对我来说是默认运行的,是因为我在我的 ~/.ghc/ghci.conf 中添加了 :set -cpp。我没有想到这一点,直到我记起它不是默认行为。 - David Miani
2
@nanothief:啊,这就解释了。使用“LANGUAGE”编译指示符来扩展是更好的选择的另一个原因。 - hammar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接