如何使用`stack`在Main的上下文中执行Haskell代码?

时间:2016-02-09 10:03:34

标签: bash unix haskell haskell-stack

我正在做这样的事情

$ stack eval 'functionDefinedInMain $ 1 + 1' > test1.txt

然而,当我执行时,stderr告诉我

<interactive>:1:1: Not in scope: ‘functionDefinedInMain’

我还试图将代码传递到stack ghci,这让我更接近:

$ echo 'functionDefinedInMain $ 1+1' | stack ghci > test2.txt
Using main module: 1. Package `exp-proj' component exe:exp-proj with main-is file: /home/wizek/sandbox/exp-proj/exp-proj/src/Main.hs
Configuring GHCi with the following packages: exp-proj

$ cat test2.txt
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
[1 of 5] Compiling Utils            ( /home/wizek/sandbox/exp-proj/exp-proj/src/Utils.hs, interpreted )
[2 of 5] Compiling Vertex           ( /home/wizek/sandbox/exp-proj/exp-proj/src/Vertex.hs, interpreted )
[3 of 5] Compiling Edge             ( /home/wizek/sandbox/exp-proj/exp-proj/src/Edge.hs, interpreted )
[4 of 5] Compiling Lib              ( /home/wizek/sandbox/exp-proj/exp-proj/src/Lib.hs, interpreted )
[5 of 5] Compiling Main             ( /home/wizek/sandbox/exp-proj/exp-proj/src/Main.hs, interpreted )
Ok, modules loaded: Utils, Vertex, Edge, Lib, Main.
*Main Edge Lib Utils Vertex> 3
*Main Edge Lib Utils Vertex> Leaving GHCi.

如您所见,3污染了输出(此示例中的数字GHCi)文件。

我想要改为使用该文件的内容:

$ cat test2.txt
3

我怎么能

  1. 使用我stack eval文件中指定的.cabal加载我的所有项目模块,以在上下文中执行代码,或
  2. 将GHCi输出抑制为stdout? (我不介意GHCi是否将信息放在stderr
  3. $ stack --version
    Version 1.0.2, Git revision fa09a980d8bb3df88b2a9193cd9bf84cc6c419b3 (3084 commits) x86_64
    

    编辑:添加了unix和bash标记,因为即使没有{{1}的明确支持,也可以通过将不同的stack / GHCi命令组合在一起来实现此目的。 }。

2 个答案:

答案 0 :(得分:3)

-e中的ghc -e标志需要Haskell表达式,并且Prelude上只有默认访问权限。您需要使用完全限定的其他功能:

stack eval 'Library.someFunc $ 1+1'
            ^^^^^^^^

但是,这仅适用于以下情况:

  1. 该模块必须是的一部分,而不是可执行文件
  2. 必须从模块中导出表达式。
  3. 如果您只是尝试使用Main.xxx,请确保Main是您图书馆中的可见模块。这也得出结论,您不能将eval用于仅可执行项目。但是,这可能会导致奇怪的问题。例如,GHCi将尝试两次导入Main,一次通过可执行文件,一次通过库。

    实施例

    $ stack new exp-eval simple
    $ cd exp-eval
    $ cat addition >> exp-eval.cabal
    $ stack eval 'Main.main'
    

    addition具有以下内容:

    library
      hs-source-dirs:      src 
      exposed-modules:     Main
      default-language:    Haskell2010
      build-depends:       base >= 4.7 && < 5 
    

答案 1 :(得分:0)

我不太了解你想要做什么 - 你想要执行主 - 然后使用

$> stack runghc ./src/Main.hs > test.txt

$> stack build
$> stack exec -- modulename > test.txt

调用已编译的二进制文件。

如果您有一个在main中导出的函数,最简单的方法是使用stack ghci并从内部调用该函数 - 如果它生成String,则可以使用

writeFile "test.txt" (myfunction parameter1 parameter2)

获得理想的结果。

之前我没有使用stack eval,但我想你必须在库中导出你的函数,我猜你的cabal文件说你只有一个可执行文件的导出 - 给你更多信息我需要你的cabal文件。