Both versions of the gtk package are visible when running `stack ghc` - haskell

A minimal reproduction can be found here:
https://github.com/IvanMalison/stack-gtk2hs-bug
Everything works as expected when I use normal stack commands, but when I run the failing command:
stack ghc -- --make main.hs
I get the following error:
main.hs:3:1: error:
Ambiguous interface for ‘Graphics.UI.Gtk’:
it was found in multiple packages: gtk-0.14.6 gtk3-0.14.6
main.hs:4:1: error:
Ambiguous interface for ‘Graphics.UI.Gtk.Abstract.Widget’:
it was found in multiple packages: gtk-0.14.6 gtk3-0.14.6
main.hs:5:1: error:
Ambiguous interface for ‘Graphics.UI.Gtk.Layout.Table’:
it was found in multiple packages: gtk-0.14.6 gtk3-0.14.6
The output of stack exec ghc-pkg -- --no-user-package-db list is https://gist.github.com/f19f900988f49e4d03cd61f1cab48baa . This output makes me expect that the reason that this is happening is that some other stack install required gtk (not gtk3 which is what is specified as a dependency in this package) and somehow this package is visible from the stack ghc command for some reason.
Am I misunderstanding the stack ghc command? Shouldn't this essentially do the same thing as stack build?

There's no builtin way to do this with stack currently. However, it is possible to get stack ghci to do this. The most straightforward way to do it is to make a cabal package which has the executable target. However, if you really want to just use straight ghc, there is a way. Copy-pasting from my comment here:
stack ghc works a bit differently than stack ghci. It's essentially a synonym for stack exec -- ghc, which will run the right compiler with the right databases, but won't set up anything related to your local packages like include directories etc. Note that stack ghci takes TARGET arguments whereas stack ghc does not. Retrospectively, this is a bit inconsistent, but stack ghc came before stack ghci.
It does make sense to have the ability to do something like this, though not sure how to best achieve that. Some potential options:
--no-interactive argument on stack ghci. Would be a bit obtuse. Weird to run a ghci command when, though it would be using the stack ghci logic.
Add --target TARGET option to stack ghc, to tell it to use the environment of a particular local package target.
Here's a workaround for now. Put the following in ~/.local/bin/stack-run-ghc.sh and make it user executable:
#/bin/sh
ghc $(echo "$*" | sed 's/--interactive//g')
This takes the arguments, removes --interactive, and calls ghc. With this, I can build stack using ghc via the following:
stack ghci --with-ghc stack-run-ghc.sh --ghci-options src/main/Main.hs

Related

module ‘main:Main’ is defined in multiple files

I have tried to load a file by typing ghc Interact Interact.hs
This produces the following error:
<no location info>: error:
module ‘main:Main’ is defined in multiple files: Interact.hs
Interact.hs``
I therefore searched on stack overflow and found the answers here (stack ghci with error module ‘main:Main’ is defined in multiple files:) which seem relevant.
However, unfortunately, they are undecipherable for the uninitiate, taking for granted concepts that I do not have at my disposal. For example, what are the following two sentences even suggesting?
I would run Stack with --verbose and see how GHCi is being invoked, and double-check the package.yaml and generated Cabal file. (If you edit your question to include that, we may be able to offer more specific help with it.)
I don't know what it means to check a package or a generated Cabal file (nor what a generated cabal file in). There is not definition of what is meant by 'invoked'.
I'm sure that the answers in the link above are very useful to those who already possess the requisite concepts. But to the uninitiated, they don't help.
Can someone please provide answers which clarify the particular questions I have above, so that I can understand the information provided in stack ghci with error module ‘main:Main’ is defined in multiple files:?
I typed stack --verbose into the terminal and this produced
Missing: COMMAND|FILE
Usage: stack [--help] [--version] [--numeric-version] [--hpack- numeric-version]
[--docker*] [--nix*] ([--verbosity VERBOSITY] | [-v|--verbose] |
[--silent]) [--[no-]time-in-log] [--stack-root STACK-ROOT]
[--work-dir WORK-DIR] [--[no-]system-ghc] [--[no-]install-ghc]
[--arch ARCH] [--ghc-variant VARIANT] [--ghc-build BUILD]
[-j|--jobs JOBS] [--extra-include-dirs DIR] [--extra-lib-dirs DIR]
[--with-gcc PATH-TO-GCC] [--with-hpack HPACK]
[--[no-]skip-ghc-check] [--[no-]skip-msys] [--local-bin-path DIR]
[--[no-]modify-code-page] [--[no-]allow-different-user]
[--[no-]dump-logs] [--resolver RESOLVER] [--compiler COMPILER]
[--[no-]terminal] [--color WHEN] [--terminal-width INT]
[--stack-yaml STACK-YAML] COMMAND|FILE
You gave GHC the same file twice. GHC will automatically try finding a file by adding appropriate file extensions, so when you gave it Interact it found Interact.hs once, then you gave it the same file again.
I'm not sure what you were trying to achieve with your command. If you are trying to add a directory called Interact that GHC will search for modules, you want ghc -iInteract Interact.hs. If you are trying to name the binary that GHC outputs, you want ghc -o Interact Interact.hs (but that would be the default name anyway, so in that case you might as well just use ghc Interact.hs).
The stack documentation is probably irrelevant to you since you are using ghc directly.

How to tell haskell stack to use an installed package?

I've been able to use the Data.Tuple.Extra module after installing the extra package by stack build extra. But the same doesn't apply to the Data.List.Unique module (https://hackage.haskell.org/package/Unique-0.4.7.8/docs/Data-List-Unique.html). According to the website, it's included in package Unique. So, I installed it with
$ stack build Unique
The installation seems to have been successful because I didn't see any error messages. But
$ cat try.hs
import Data.List.Unique
main = do putStrLn "hello"
$ stack runghc try.hs
try.hs:1:1: error:
Could not find module ‘Data.List.Unique’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
1 | import Data.List.Unique
| ^^^^^^^^^^^^^^^^^^^^^^^
$
The output from stack runghc -v try.hs is too big for me to analyze . . .
Note: I've modified the question to focus on the installation and use of modules. Following the answers provided below, I'm able to run the program using an option. Still, it would be nice if one wouldn't need to use a package option.
stack build doesn't "install" the package globally for use with every compilation, and runghc can't pick up Stack packages. It's meant to be a more or less direct execution of GHC.
You can specify packages to use if you run your program with stack try.hs, as described in the docs. In that case, you'll be able to specify packages to use with specially formatted comments, like this:
-- stack script --package Unique
import Data.List.Unique
main = do putStrLn "hello"
The Unique dependency can be specified by passing the --package option to runghc:
stack runghc --package Unique try.hs
Alternatively, you can make try.hs a Stack script, as illustrated by Fyodor Soikin's answer.
If you plan to develop try.hs into more than a standalone file, consider setting up a Stack project. See the Hello World example in the Stack User Guide for initial guidance on that.

Compiling a haskell script with external dependencies without cabal

I'm relatively new to Haskell and I realize I might be swimming against the stream here, but nonetheless, I'll ask:
Say I have a short Haskell script:
import Data.List.Split (splitOn)
main :: IO ()
main = do
let orders = splitOn "x" "axbxc"
putStrLn $ head orders
If I used only standard functions I could compile this with ghc <script.hs>. Because I depend on the split package to provide the splitOn function, the compilation fails.
Now, I have no difficulties setting up a cabal project with a project.cabal and a Setup.hs file in order to get this to actually compile. However, this feels like a lot of extra boilerplate for a standalone script.
So, is there a way to compile a single .hs file against some external package? Something similar to what in Python would be done by pip install something, "installing the package into the interpreter", i.e. is there a way to install extra packages "into ghc", so that I for instance only need to provide some extra linking flag to ghc?
The Cabal equivalent of the Stack script in bradrn's answer would be:
#!/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
The script can be run with cabal run, or directly by giving it execute permission. If need be, version bounds can be added as usual to the build-depends on the top of the script.
(Note this isn't literally a solution without Cabal, as doing this with GHC alone, even if it is possible, wouldn't be worth the trouble. In any case, it certainly avoid the boilerplate of needing multiple files.)
If you use Stack, the simplest way to do this is to write a ‘Stack script’, which is a Haskell file with a description of the required packages in the first line (really an invocation of stack specifying the appropriate command line arguments). An example (slightly modified from the docs):
$ 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!
This script uses the turtle package; when run, Stack downloads and builds this dependency, after which it is available in the script. (Note that the second time it is run, turtle has already been built so does not need to be rebuilt again.)
As it happens, the --package command in Stack is not limited to scripts. It can be used with other Stack commands as well! For instance, to compile your program, you should be able to run stack ghc --resolver lts-16.27 --package split -- -ghc-options your-program-name.hs. And stack ghci --package split will give you a GHCi prompt where you can import Data.List.Split.
(Note: This answer focuses on Stack rather than Cabal, simply because I don’t know Cabal very well. However, I believe all this can be done using Cabal as well. For instance, I do know that Cabal has something very similar to the Stack scripts I mentioned above, though I can’t remember the syntax just at the moment.)
EDIT: See #duplode’s answer for how to do this with Cabal.
You can install into the default environment for the current user by doing cabal install --lib split. The package should then be available to ghc and ghci without needing any special options.
More information is at the bottom of this section in the Cabal manual. The v2 commands that it uses are the default now so if you have a fairly new cabal you can just use install rather than v2-install.
I think this is the quintessential entry point to the package management battle in Haskell. It's not there's not enough advice, but there's so much, each with its own caveats and assumptions. Climbing that mountain for the sake of splitOn feels to the newbie like they're Doing It Wrong.
After spending far too much time trying each permutation, I've collated the fine answers here, and many, many others from elsewhere, put them to the test, and summarised the results. The full write up is here.
The pertinent summary of solutions is:
Install globally
You can still do global installs with cabal install --lib the-package.
Use Stack as a run command
You can use stack directly, eg: stack exec --package containers --package optparse-generic [...and so on] -- runghc hello.hs
Create a Stack project
The real deal. Run stack new my-project hraftery/minimal, put your code in Main.hs and your dependencies in my-project.cabal (and maybe stack.yaml - check the article), and then run stack build to automagically pull and build all dependencies.
Use a Stack script
Make your Haskell file itself an executable Stack script. Add -- stack --resolver lts-6.25 script --package the-package to the top of your .hs file and set its executable bit.
For my Edit/Test/Run workflow (eg. using VS Code, GHCi and GHC respectively), I found it pretty clear what works in practice. In summary:
Amongst a chorus of discouragement, Global Installs suit what I know of your use case just fine.
Where Global Installs don't make sense (eg. for managing dependency versions or being portable) a Stack project starting from my minimal template is a smooth transition to a more sophisticated and popular method.

How to fix hdevtools - "GHC_PACKAGE_PATH is incompatible.." error

I'm a haskell beginner, I use the advent of code as learning examples.
When setting up for this year I reinstalled stack (on a new machine, however copied most dotfiles over) and was starting from my last years notes and was not able to get hdevtools working again.
I have set up a new project with stack new advent2019. In case it matters stack build on the "empty" project seems to take several minutes - seems much longer than last year. I install hdevtools with stack build hdevtools.
When I run stack exec hdevtools -- check src/Lib.hs I get following error:
Cabal error: hdevtools: Use of GHC's environment variable GHC_PACKAGE_PATH is incompatible
with Cabal. Use the flag --package-db to specify a package database (it can be
used multiple times).
So far I tried:
I checked my shell and did an rg --no-ignore over my home directory to confirm GHC_PACKAGE_PATH is not set by me. Also over the project directory.
I was not able to figure out how to use the mentioned --package-db flag - putting it after hdevtools I get an unknown flag error, putting it to stack I get an invalid option.
stack exec --no-ghc-package-path hdevtools -- check src/Lib.hs - mentioned here
I deleted all possible related files: ~/.local/bin/hdevtools, everything from ~/.stack, all ~/.ghc*.
None helped with the error.
I suppose I overlooked something obvious - however can you help point it out?
For completeness:
on OS X, 10.15.1
stack --version: Version 1.9.3, Git revision 40cf7b37526b86d1676da82167ea8758a854953b (6211 commits) x86_64 hpack-0.31.1
stack ghc -- --version: The Glorious Glasgow Haskell Compilation System, version 8.6.5
stack path:
stack-root: /Users/me/.stack
project-root: /Users/me/Code/advent2019
config-location: /Users/me/Code/advent2019/stack.yaml
bin-path: /Users/me/.stack/snapshots/x86_64-osx/lts-14.16/8.6.5/bin:/Users/me/.stack/compiler-tools/x86_64-osx/ghc-8.6.5/bin:/Users/me/.stack/programs/x86_64-osx/ghc-8.6.5/bin:/usr/local/texlive/2018basic/bin/x86_64-darwin:/Users/me/.local/bin/:/Users/me/.gem/bin:/Users/me/.yarn/bin:/Users/me/Library/Python/3.7/bin/:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Library/TeX/texbin:.:/Applications/Wireshark.app/Contents/MacOS
programs: /Users/me/.stack/programs/x86_64-osx
compiler-exe: /Users/me/.stack/programs/x86_64-osx/ghc-8.6.5/bin/ghc
compiler-bin: /Users/me/.stack/programs/x86_64-osx/ghc-8.6.5/bin
compiler-tools-bin: /Users/me/.stack/compiler-tools/x86_64-osx/ghc-8.6.5/bin
local-bin: /Users/me/.local/bin
extra-include-dirs:
extra-library-dirs:
snapshot-pkg-db: /Users/me/.stack/snapshots/x86_64-osx/lts-14.16/8.6.5/pkgdb
local-pkg-db: /Users/me/Code/advent2019/.stack-work/install/x86_64-osx/lts-14.16/8.6.5/pkgdb
global-pkg-db: /Users/me/.stack/programs/x86_64-osx/ghc-8.6.5/lib/ghc-8.6.5/package.conf.d
ghc-package-path: /Users/me/Code/advent2019/.stack-work/install/x86_64-osx/lts-14.16/8.6.5/pkgdb:/Users/me/.stack/snapshots/x86_64-osx/lts-14.16/8.6.5/pkgdb:/Users/me/.stack/programs/x86_64-osx/ghc-8.6.5/lib/ghc-8.6.5/package.conf.d
snapshot-install-root: /Users/me/.stack/snapshots/x86_64-osx/lts-14.16/8.6.5
local-install-root: /Users/me/Code/advent2019/.stack-work/install/x86_64-osx/lts-14.16/8.6.5
snapshot-doc-root: /Users/me/.stack/snapshots/x86_64-osx/lts-14.16/8.6.5/doc
local-doc-root: /Users/me/Code/advent2019/.stack-work/install/x86_64-osx/lts-14.16/8.6.5/doc
dist-dir: .stack-work/dist/x86_64-osx/Cabal-2.4.0.1
/Users/me/Code/advent2019/.stack-work/install/x86_64-osx/lts-14.16/8.6.5/hpc
local-bin-path: /Users/me/.local/bin
ghc-paths: /Users/me/.stack/programs/x86_64-osx
The --no-ghc-package-path solution should have worked. However, you can just run hdevtools outside of Stack. On a Linux machine, if I run the following set of commands exactly:
$ stack new advent2019
$ cd advent2019
$ stack build
$ stack install hdevtools
$ hdevtools check src/Lib.hs
then hdevtools starts without error and runs in the background.
If your shell can't find hdevtools, it may be that ~/.local/bin is not in your path, so add it or try this instead:
$ ~/.local/bin/hdevtools check src/Lib.hs
Turns out I overlooked the .cabal directory in my purge. Though still had to also wipe .stack before installing hdevtools. Also had to build test separately so I would get dependency errors.
I don't think this is a solution for someone who uses haskell productively. Reminds me of my Windows 95 days where support told you to format and reinstall for every issue.

Cannot load vector in ghci due to shadowed dependencies

Whenever I try to load the vector package in ghci I get the following:
Prelude> :set -package vector
cannot satisfy -package vector:
vector-0.12.0.1-6mmeV84KOvJADXavl6mOiY is unusable due to shadowed dependencies:
primitive-0.6.2.0
(use -v for more information)
vector is installed in my cabal sandbox and I'm running cabal repl to get to ghci. Is importing vector simply not possible or is there a way around it? I'm on OSX.
I'm not sure what is causing that error message in your case, but one possibility is to use Stack's ghci command like so:
stack ghci --package vector
You can get Stack by following the instructions at https://haskell-lang.org/get-started, or since you're on OS X by running:
curl -sSL https://get.haskellstack.org/ | sh
There was an issue with full 8.2.1 binary platform builds that's just been resolved: https://mail.haskell.org/pipermail/haskell-cafe/2017-October/127979.html
This was likely an instance of that.

Resources