问题描述
我对 Haskell 比较陌生,我意识到我可能会在这里逆流而上,但尽管如此,我还是会问:
import Data.List.Split (splitOn)
main :: IO ()
main = do
let orders = splitOn "x" "axbxc"
putStrLn $ head orders
如果我只使用标准函数,我可以用 ghc <script.hs>
编译它。因为我依赖split
包提供splitOn
函数,编译失败。
现在,我可以轻松地使用 project.cabal
和 Setup.hs
文件设置 cabal 项目,以便实际编译。然而,对于独立脚本来说,这感觉就像是很多额外的样板。
那么,有没有办法针对某个外部包编译单个 .hs 文件? 类似于 Python 中通过 pip install something
完成的操作,“将包安装到解释器”,即有没有办法将额外的包安装到“ghc”中,例如,我只需要向 ghc 提供一些额外的链接标志?
解决方法
如果你使用Stack,最简单的方法是写一个'Stack script',它是一个Haskell文件,第一行描述了所需的包(实际上是调用{{ 1}} 指定适当的命令行参数)。一个例子(从 the docs 稍微修改):
stack
此脚本使用 $ cat turtle-example.hs
-- stack --resolver lts-6.25 script --package turtle
{-# LANGUAGE OverloadedStrings #-}
import Turtle
main = echo "Hello World!"
$ stack ./turtle-example.hs
Completed 5 action(s).
Hello World!
$ stack ./turtle-example.hs
Hello World!
包;运行时,Stack 下载并构建此依赖项,此后它在脚本中可用。 (请注意,第二次运行时,turtle
已经构建完毕,因此无需再次重新构建。)
碰巧的是,Stack 中的 turtle
命令不仅限于脚本。它也可以与其他堆栈命令一起使用!例如,要编译您的程序,您应该能够运行 --package
。并且 stack ghc --resolver lts-16.27 --package split -- -ghc-options your-program-name.hs
会给您一个 GHCi 提示,您可以在其中stack ghci --package split
。
(注意:这个答案侧重于 Stack 而不是 Cabal,仅仅是因为我不太了解 Cabal。但是,我相信这一切也可以使用 Cabal 来完成。例如,我确实知道 Cabal 有一些东西与我上面提到的 Stack 脚本非常相似,虽然我现在不记得语法。)
编辑:有关如何使用 Cabal 执行此操作的信息,请参阅 @duplode’s answer。
,与 bradrn's answer 中的 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
该脚本可以使用 cabal run
运行,也可以直接授予它执行权限。如果需要,可以像往常一样将版本边界添加到脚本顶部的 build-depends
中。
(请注意,如果没有 Cabal,这实际上并不是一个解决方案,因为单独使用 GHC 执行此操作,即使可能,也不值得麻烦。无论如何,它肯定避免了需要多个文件的样板。 )
,您可以通过执行 cabal install --lib split
安装到当前用户的默认环境中。然后,该软件包应该可用于 ghc 和 ghci,而无需任何特殊选项。
更多信息位于 this section in the Cabal manual 的底部。它使用的 v2
命令现在是默认的,所以如果你有一个相当新的阴谋集团,你可以只使用 install
而不是 v2-install
。