我对 Haskell 比较陌生,我意识到我可能会逆流而上,但尽管如此,我会问:
假设我有一个简短的 Haskell 脚本:
import Data.List.Split (splitOn)
main :: IO ()
main = do
let orders = splitOn "x" "axbxc"
putStrLn $ head orders
Run Code Online (Sandbox Code Playgroud)
如果我只使用标准函数,我可以用ghc <script.hs>
. 因为我依赖split
包提供splitOn
功能,所以编译失败。
project.cabal
现在,我可以毫无困难地使用和文件设置一个 cabal 项目,Setup.hs
以便实际编译它。然而,对于独立脚本来说,这感觉像是很多额外的样板。
那么,有没有办法针对某些外部包编译单个 .hs 文件?类似于 Python 中的操作可以通过pip install something
“将包安装到解释器中”来完成,即有没有办法将额外的包“安装到 ghc”中,这样我只需要向 ghc 提供一些额外的链接标志?
dup*_*ode 11
Bradrn 答案中 Stack 脚本的 Cabal 等效项是:
#!/usr/bin/env cabal
{- cabal:
build-depends: base
, split
-}
import Data.List.Split (splitOn)
main :: IO ()
main = do
let orders = splitOn "x" "axbxc"
putStrLn $ head orders
Run Code Online (Sandbox Code Playgroud)
该脚本可以使用 运行cabal run
,也可以通过授予其执行权限直接运行。如果需要,可以像往常一样将版本边界添加到build-depends
脚本顶部。
(请注意,这实际上并不是没有 Cabal 的解决方案,因为单独使用 GHC 来实现这一点,即使可能,也不值得这么麻烦。无论如何,它肯定避免了需要多个文件的样板。)
如果您使用Stack,最简单的方法是编写一个 \xe2\x80\x98Stack 脚本\xe2\x80\x99,这是一个 Haskell 文件,第一行包含所需包的描述(实际上是调用stack
指定适当的命令行参数)。一个示例(根据文档稍作修改):
$ cat turtle-example.hs\n-- stack --resolver lts-6.25 script --package turtle\n{-# LANGUAGE OverloadedStrings #-}\nimport Turtle\nmain = echo "Hello World!"\n$ stack ./turtle-example.hs\nCompleted 5 action(s).\nHello World!\n$ stack ./turtle-example.hs\nHello World!\n
Run Code Online (Sandbox Code Playgroud)\n该脚本使用该turtle
包;运行时,Stack 下载并构建此依赖项,然后在脚本中可用。(请注意,第二次运行时,turtle
已经构建完毕,因此不需要再次重建。)
碰巧的是,--package
Stack 中的命令并不限于脚本。它也可以与其他堆栈命令一起使用!例如,要编译您的程序,您应该能够运行stack ghc --resolver lts-16.27 --package split -- -ghc-options your-program-name.hs
. 并stack ghci --package split
会在可能的情况下为您提供 GHCi 提示import Data.List.Split
。
(注:这个答案关注的是Stack而不是Cabal,只是因为我不太了解Cabal。但是,我相信所有这些也可以使用Cabal来完成。例如,我确实知道Cabal有与我上面提到的 Stack 脚本非常相似,尽管我现在无法记住语法。)
\n编辑:有关如何使用 Cabal 执行此操作,请参阅@duplode\xe2\x80\x99s 答案。
\n