在没有 cabal 的情况下编译具有外部依赖项的 haskell 脚本

Ben*_*dik 7 haskell cabal

我对 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 来实现这一点,即使可能,也不值得这么麻烦。无论如何,它肯定避免了需要多个文件的样板。)


bra*_*drn 6

如果您使用Stack,最简单的方法是编写一个 \xe2\x80\x98Stack 脚本\xe2\x80\x99,这是一个 Haskell 文件,第一行包含所需包的描述(实际上是调用stack指定适当的命令行参数)。一个示例(根据文档稍作修改):

\n
$ 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已经构建完毕,因此不需要再次重建。)

\n

碰巧的是,--packageStack 中的命令并不限于脚本。它也可以与其他堆栈命令一起使用!例如,要编译您的程序,您应该能够运行stack ghc --resolver lts-16.27 --package split -- -ghc-options your-program-name.hs. 并stack ghci --package split会在可能的情况下为您提供 GHCi 提示import Data.List.Split

\n

(注:这个答案关注的是Stack而不是Cabal,只是因为我不太了解Cabal。但是,我相信所有这些也可以使用Cabal来完成。例如,我确实知道Cabal有与我上面提到的 Stack 脚本非常相似,尽管我现在无法记住语法。)

\n

编辑:有关如何使用 Cabal 执行此操作,请参阅@duplode\xe2\x80\x99s 答案。

\n