Error: module ‘main:Course’ is defined in multiple files: src/Course.hs - haskell

I'm trying to start working on https://github.com/system-f/fp-course. After running stack ghci, it finishes with:
...
[51 of 51] Compiling Test.Loader ( src/Test/Loader.hs, interpreted )
Ok, 51 modules loaded.
Loaded GHCi configuration from /home/lpied/haskell/fp-course/.ghci
<no location info>: error:
module ‘main:Course’ is defined in multiple files: src/Course.hs
src/Course.hs
Failed, 51 modules loaded.
Loaded GHCi configuration from /tmp/haskell-stack-ghci/75d10d48/ghci-script
Any idea why it's complaining that the module is defined in the same file (src/Course.hs)?

Can you try using stack exec ghci instead? stack ghci is probably recognizing the src directory and adding -isrc to the ghci command line, and then the .ghci file in the course root directory is also adding -isrc to the ghci command line. GHC probably doesn't de-duplicate its search path, so it acts like you have two separate directories which both happen to be named src.

Related

stack ghci with error module ‘main:Main’ is defined in multiple files:

I have a small haskell program which builds and executes with stack ok. When I start it with stack ghci I have an error message which I do not understand and cannot proceed.
GHCi, version 8.10.4: https://www.haskell.org/ghc/ :? for help
[1 of 3] Compiling Lib ( /home/frank/Workspace11/primo/src/Lib.hs, interpreted )
[2 of 3] Compiling YamlRead ( /home/frank/Workspace11/primo/src/YamlRead.hs, interpreted )
[3 of 3] Compiling Main ( /home/frank/Workspace11/primo/app/Main.hs, interpreted )
Ok, three modules loaded.
Loaded GHCi configuration from /home/frank/Workspace11/primo/.ghci
<no location info>: error:
module ‘main:Main’ is defined in multiple files: /home/frank/Workspace11/primo/app/Main.hs
/home/frank/Workspace11/primo/app/Main.hs
I do not see why the same Main is listed twice in the exact same file.
I had a somewhat similar warning message about Paths_primo which is a known bug ( Stack issue #5439 ) and I fixed following the advice see.
What is the cure against this error? I have not used stack much - am I doing something wrong?
This looks like a sign that Main.hs or Main is inadvertently listed multiple times in your Stack package.yaml, in such a way that ghc is invoked with multiple occurrences of it.
This error is possible to reproduce easily with GHC alone, for example:
> echo 'main = putStrLn "hello"' > Hello.hs
> ghc Hello Hello.hs
<no location info>: error:
module ‘main:Main’ is defined in multiple files: Hello.hs Hello.hs
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 can think of several possible reasons for this, such as literally listing Main or Main.hs multiple times (e.g. in exposed-modules, other-modules, main-is); or an interaction like a missing option value in the ghc-options field causing subsequent flags to be misinterpreted.
Main.hs can be listed multiple times in GHCi invocation when it is present in multiple components. Typical way when this happens is:
You create a project with stack new which contains single src/Main.hs file, so package.yaml has an executable entry and no library entry.
Then you add a library and use source-dir: src. Now Main.hs is listed in two components: myapp-lib and myapp-lib-exe. Assuming you package name is myapp.
To solve the problem you should move Main.hs to app dir and update executables:source-dirs to app in package.yaml.
So the problem may happen when Main.hs is listed in multiple components in package.yaml, for example in executables and library.

Can I persuade stack / ghci to *only* load the local .ghci file?

I have a .ghci in my local project directory, and another one in my $HOME. When I do a stack ghci, then $HOME/.ghci is loaded first, followed by $PWD/.ghci. Is it possible to have ONLY the local .ghci be loaded, and the global one ignored?
I could do a stack exec -- ghci -ignore-dot-ghci, but then, none is loaded.
What I also tried is:
stack exec -- ghci -ignore-dot-ghci -W .ghci
The idea being to first tell ghci not to load anything and then explicitly requesting the local .ghci file, but this gives the error message Warning: ignoring unrecognised input `.ghci'
GHCi has a -ghci-script flag which can be used alongside -ignore-dot-ghci. It can be used with stack ghci through --ghci-options:
stack ghci --ghci-options "-ignore-dot-ghci -ghci-script .ghci"
For the sake of completeness, here is the corresponding cabal repl invocation:
cabal repl --repl-options "-ignore-dot-ghci" --repl-options "-ghci-script .ghci"

Can GHCI's :add command accept a path that is relative to one's home directory?

This is the GHC manual documentation for :add:
:add[*] ⟨module⟩
Add ⟨module⟩(s) to the current target set, and perform a reload. Normally pre-compiled code for the module will be loaded if available, or otherwise the module will be compiled to byte-code. Using the * prefix forces the module to be loaded as byte-code.
I can tell from experimentation that ⟨module⟩ doesn't actually have to be the name of a module; it can also be a file path. And if it is not an absolute path, it seems to be resolved relative to the current directory from which the REPL was launched.
Is it possible to refer :add a path that is relative to one's home directory?
For example, I'd like to include $HOME/.ghci/imports.hs from my global GHCI config. (For the motivation behind this, see Can a GHCI config file use CPP macros?)
I've tried the obvious
:add $HOME/.ghc/imports.hs
but it doesn't work:
<no location info>: error: can't find file: $HOME/.ghc/imports.hs
Failed, modules loaded: none.
Use ~ instead of $HOME.
λ :add ~/Documents/Code/Haskell/Ackermann
[1 of 1] Compiling Ackermann ( /Users/rampion/Documents/Code/Haskell/Ackermann.hs, interpreted )
Ok, modules loaded: Ackermann.

stack ghci not loading up local modules?

I have
mainLogger.hs
Logger.hs
in my local directory where the mainLogger.hs reference the Logger module.
When in stack ghci I :load mainLogger.hs I get the following error message :
mainLogger.hs:6:18:
Could not find module ‘Logger’
It is not a module in the current program, or in any known package.
However if I can compile stack exec -- ghc mainLogger.hs and run stack runghc mainLogger2.hs or have stack exec -- ghci load the module correctly.
Anyone knows what is preventing stack ghci from locating module in the local directory ?
ps : I am not using any cabal file or stack.yaml file in this directory, so it falls back onto my global stack.yaml config
You should be able to load both if you do it at the same time:
:load Logger.hs mainLogger.hs
I don't know if you can get GHCi to look for the missing module in the current folder if you have no cabal file but if you create/initialize one this is not necessary.
This issue should now be fixed in the latest version of stack. It seems that when a module imported a local module, stack wasn't including the local directory in its module search path. In the latest 1.5.1. version of stack, this has been fixed - so you should be able to just type
stack ghci mainLogger.hs

Loading Haskell Modules that have dependencies

I'm unsure what my issue is here. I have a trio of modules A.hs, B.hs, and C.hs. All are located at C:\..path...\folder and modules B and C both import from A.
That is, both modules B and C contain the line import A
I can :l C:\..path..\folder\A.hs in gchi and play with its contents; however, ghci gives the following error when I try to :l C:\..path..\folder\B.hs or :l C:\..path..\folder\C.hs
Could not find module `A'
Use -v to see a list of the files searched for.
Failed, modules loaded: none.
Which I find odd because I had no trouble compiling B.hs to B.exe and running the executable. How can I compile and run a module that I can't load into ghci? Or, why would an import succeed at compile time but fail in loading; especially when that very module being imported is itself load-able?
By default, ghci searches only in the current directory for imported modules. To start with, the current directory is the one used to launch ghci; but it can be changed from within ghci with the :cd command. Thus, you could
> :cd C:\...path...\folder
> :l B.hs
and this should find both B.hs and A.hs in what is now the current directory. Alternately (and especially if you have modules in multiple directories) you can launch ghci with the -i command line option to add directories to its module search path. For example, in your command prompt you might
% ghci -iC:\...path...\folder
> :l B.hs
which will instruct ghci to include C:\...path...\folder in its search path, and therefore find B.hs and A.hs there even if it is not the current directory.

Resources