Compile stack script instead of running it - haskell

The build tool stack has the feature to treat a usually compiled haskell source file as a script. (https://docs.haskellstack.org/en/stable/GUIDE/#script-interpreter)
Is it also possible to create a compiled executable the same way?
I searched the help section of stack and stack script, but could not find an options that make this possible.
script.hs:
#!/usr/bin/env stack
{-
stack script
--resolver lts-13.14
--package turtle
-}
main = print "hello"
So if given it the right permissions, this file can be executed. I guess behind the scenes stack compiles the file and then just runs it. And I'd like to just get the compiled intermediate binary.

No, it's not compiled. It's run through runhaskell which is a Haskell interpreter. If you want to compile it... do that. Instead of running the script,
take the --resolver and --package options from the script comment and pass them like this
stack ghc --resolver lts-13.14 --package turtle test.hs

The script command takes both --compile and --optimize as flags, which will instruct Stack to first compile to an executable (optionally with -O2 optimization level) before running.

Related

global GHC from Stack?

I have happily installed Stack, and run my code with stack ghci or stack exec and whatnot.
I would like to use vscode-haskell, and that requires a ghc available in the PATH.
Is it possible to create a ghc command available globally using stack? (e.g. some suitable commans in my powershell/bash profile)
ps. Close duplicates that did not help me are
Using stack ghc as replacement of ghc but only talks about makefiles
Haskell Stack doesn't use system Ghc is about making Stack use a system GHC if it is available which is not the case for me
Haskell stack with global ghc which is close to a dupplicate of [2]

Haskell standalone executable without using 'stack exec'

How would one go about creating an executable from a stack generated framework (stack new myprog simple)?
myprog.cabal shows myprog as executable that can be executed using stack exec myprog.
However: using ./myprog will not work. Not unless I call ghc --make src/Main.hs. This works obviously and nicely embeds the modules, but now the executable is called Main.
Is there a way to have stack compile myprog as a complete executable that can be called from anywhere assuming the environmental path is set?
As you may already be aware, stack build builds the executable, but then places it in a stack-specific path which can most easily be accessed using stack exec. However, there is another command: stack install, which then copies the executable to a convenient location. Normally the default location is in ~/.local/bin (I think), but you can use stack install --local-bin-path <PATH> to copy the executable to <PATH>. For instance, use stack install --local-bin-path . to place the executable in your current working directory, or use stack install --local-bin-path bin to place it in your ./bin/ directory. You can then run the executable using <PATH>/my-exe.

Passing RTS-opts to `stack test`

How can I pass RTS options to the test-suite of my project using stack?
stack exec allows for passing options to the executable, but since stack test is a synonym for stack build --test I can't see how to accomplish this.
I'm trying to generate some JSON-formatted profiler output for my test-suite using the RTS option -pj (GHC user guide).
I can see where stack places the regular executables, but not the executables for the test-suite.

multicore parallelism with stack runghc

I had been working on a script in which I hoped to take advantage of multiple processors in my machine by swapping out mapM with Async.mapConcurrently.
Observing no speed increase in that instance, I wanted to verify that runghc can indeed utilize multiple cores.
Given a file Foo.hs:
import Control.Concurrent
main = print =<< Control.Concurrent.getNumCapabilities
If I compile the file as follows:
stack ghc -- -threaded Foo.hs
and then run it as follows:
./Foo
it returns the result 1. This is expected, as no RTS options have been supplied. Running it instead as follows:
./Foo +RTS -N
returns the number 6, as there are 6 processors in my machine (agreeing with nproc).
However, when I run the script in "interpreted mode" like so:
GHCRTS="-N" stack runghc Foo.hs
It yields the following error text:
Running /home/kostmo/.stack/programs/x86_64-linux/ghc-nopie-8.0.2/bin/ghc-pkg --no-user-package-db list --global exited with ExitFailure 1
ghc-pkg: the flag -N requires the program to be built with -threaded
Is it possible to utilize multiple cores with stack "scripts"?
Thanks for asking this question, I think stack should handle the GHCRTS environment variable specially, and opened this issue https://github.com/commercialhaskell/stack/issues/3444 and made this change https://github.com/commercialhaskell/stack/pull/3445
Unfortunately, it does not solve this case, because runghc itself (ghc) will process GHCRTS, and it is not built with the threaded runtime. So the environment variable solution cannot be used.
I think it should be possible to provide -with-rtsopts -N flag to stack script --compile, but that doesn't seem to be working, needs further investigation. This doesn't work with runghc, because it uses the interpreter.

Can Haskell be used to write shell scripts?

Is it possible to write shell scripts in Haskell and if so, how do you do it? Just changing the interpreter like so?
#!/bin/ghci
Using ghci will just load the module in GHCi. To run it as a script, use runhaskell or runghc:
#!/usr/bin/env runhaskell
main = putStrLn "Hello World!"
Well check this presentation : Practical Haskell: scripting with types
It should work if you change the interpreter to this:
#!/usr/bin/runhaskell
As of October 2016, there is a better answer to this question: use The Haskell Tool Stack script interpreter. stack-based Haskell scripts are portable because they download (and cache) the correct version of ghc and all of their package dependencies.
#!/usr/bin/env stack
-- stack --resolver lts-3.2 --install-ghc runghc
main = putStrLn "Hello World!"
See also the tutorial How to Script with Stack.
Another way to write shell scripts using Haskell is to generate the scripts, such as with bashkell. This is useful if you might want to run on systems that do not have haskell installed.

Resources