Haskell module not found. What is wrong with my project's file structure? - haskell

I have a problem with my project structure:
pic-analysis-0.1/AlgTop/Data.hs
Functions.hs
PNGModify.hs
Main.hs
Data.hs:
module AlgTop.Data (…) where
Functions.hs:
module AlgTop.Functions (…) where
import AlgTop.Data
The AlgTop.Functions module doesn't find AlgTop.Data.
I compared my project structure approach with that of ansi-terminal on Hackage (see below), but I couldn't spot any difference. What am I doing wrong?
ansi-terminal-xxx/System/Console/ANSI/Common.hs
/Unix.hs
/…
Common.hs:
module System.Console.ANSI.Common where
Unix.hs:
module System.Console.ANSI.Unix (…) where
import System.Console.ANSI.Common
Error message:
[...]
*** Chasing dependencies:
Chasing modules from: *Functions.hs
Functions.hs:9:8:
Could not find module `AlgTop.Data':
locations searched:
AlgTop/Data.hs
AlgTop/Data.lhs
[...]

If you are using ghci it is probably that you need to :set -i/.../pic-analysis-0.1. That is, include the root directory of your module hierarchy.

No need to set anything. Just cd into the root directory before invoking GHCi:
ghci AlgTop/Functions.hs

Related

Cabal update now can't load any modules from "hidden packages"

I've been working on a project and recently I did a cabal update.
I usually roll into ghci like:
$ ghci -package-db ~/.cabal/store/ghc-8.10.7/package.db
After the update loading module in my project results in even the basic Haskell modules like System.Random or MonadIO fails with the following errors when trying to load my own module called ProcessIO:
ProcessIO.hs:50:1: error:
Could not load module ‘Data.IORef.MonadIO’
It is a member of the hidden package ‘monadIO-0.11.1.0’.
You can run ‘:set -package monadIO’ to expose it.
(Note: this unloads all the modules in the current scope.)
Locations searched:
Data/IORef/MonadIO.hs
Data/IORef/MonadIO.lhs
Data/IORef/MonadIO.hsig
Data/IORef/MonadIO.lhsig
I checked that maybe the .cabal file build-depends versions might have been altered, but the cabal package.db directory contains all the right versions of the dependencies in the .cabal file. For example the error above complains abot monadIO-0.11.1.0 being hidden however: in package.db/ we see the right version exists:
monadIO-0.11.1.0-0aec75273f3fef94783e211a1933f8ac923485a963be3b6a61995d4a88dd1135.conf
I should say I haven't looked at the package.db files before because everything simple worked so there may be something telling about the .conf file name that signals something is wrong.
Either way, can't build anything and I need some help!
EDIT: posting my default environments file ~/.ghc/x86_64-linux-8.10.7/environments/default in case it matters:
clear-package-db
global-package-db
package-db /home/surya/.cabal/store/ghc-8.10.7/package.db
package-id ghc-8.10.7
package-id bytestring-0.10.12.0
...
(Let me know if I need to share more of it... or less)

Why can't the ghci find the hs file that I am trying to compile?

I'm learning Haskell for the first time and I can't see to understand why the ghci can't find the file I'm trying to compile. Especially since, I saved the file. This is my file,
import System.IO
trueAndFalse = True && False
Now this is what I ran in the compiler,
<no location info>: error: can't find file: tut-1.hs
Failed, no modules loaded.
The "Failed, no modules loaded." makes me think you're talking about ghci. If so, you can find out where ghci is looking for files with :show paths. Here's what it looks like when I try:
> :show paths
current working directory:
/home/<my username>
module import search paths:
.
The module import search paths tells you what directories it's looking in. A lone . in that list refers to the current working directory. So, for me, if I wanted a file to be easily accessible from that ghci instance, I would have to save it in /home/<my username>.
Of course there are ways of changing all of these pieces -- which paths are in the import search path, which directory is the current working directory, and so forth -- but this should get you going for simple usage.
And, by the way, a note on terminology: the GHC tool suite comes with both a compiler and an interpreter. The compiler's executable is ghc, and the interpreter's executable is ghci. Knowing about that distinction may help you avoid confusion in future conversations!

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.

Load a module in GHCi by module name when module name doesn't match file name

Suppose I am given a source file called MyModule.hs and inside it the module declaration is module My.Module where ... (note: not module MyModule where ...).
I am not permitted to alter this source file or change the directory structure where the file resides.
From reading some docs about importing modules in GHCi, it looks like there are ways to import by file name (e.g. either import or :load), but not any ways to specify a module name that will be searched for in all files of the local directory.
Is there a way to import My.Module in GHCi without doing it by specifying the file's name (only the module name) and without installing it (e.g. not building it with cabal, just quickly tossing it into GHCi by module name)?
You can't where the name contains a dot, as per the documentation
For each of these directories, it tries appending basename.extension to the directory, and checks whether the file exists. The value of basename is the module name with dots replaced by the directory separator ('/' or '\', depending on the system), and extension is a source extension (hs, lhs)...
The key part being
The value of basename is the module name with dots replaced by the directory separator ('/' or '\', depending on the system)
So your module name of My.Module will be searched for as My/Module.hs. You would need to have a directory structure like
project/
My/
Module.hs
project.cabal
And from the folder project you could run
$ cabal repl
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
> import My.Module
You can do this if your file is named MyModule.hs and your module name is MyModule, but it's just a special case of the rule above.
There are good reasons for this, namely that it enforces a structure to simplify your project structure and GHC's search algorithm. If this rule wasn't in place, what would stop me from having
project/
MyModule1.hs
MyModule2.hs
where both .hs files had the module declaration My.Module? Which one would be correct to load in GHCi if I ran import My.Module? By specifying what the filename and path is, you immediately know that the module X.Y.Z.W.Q.R.S.T is at the path X/Y/Z/W/Q/R/S/T.hs, no searching required. It reduces a lot of the ambiguity that could occur with looser module name specifications.

GHC error: Cannot continue after interface file error

I have a Haskell package that is built and installed with Cabal. Running cabal repl in the package directory works perfectly, all the module imports work, etc. When I try to use the package in another directory, imports do not complain, but when I try to use a function from the file, I get this error in GHCi
λ> import Data.Frame
λ> import Data.Frame.CSV
λ> :t fromCsvHeaders
/Users/Stian/.cabal/lib/x86_64-osx-ghc-7.8.3/frame-0.1.0.0/Data/Frame/CSV.dyn_hi
Declaration for fromCsvHeaders:
Failed to load interface for ‘Data.Frame.Internal’
Perhaps you haven't installed the "dyn" libraries for package ‘frame-0.1.0.0’?
Use -v to see a list of the files searched for.
Cannot continue after interface file error
The same happens when running ghc.
Turns out in this case there was an internal module that had not been exposed in the cabal file.

Resources