Description
Example:
cabal-version: >=1.10
name: mp-cabal
version: 0.1.0.0
build-type: Simple
library
exposed-modules: MyLib
other-modules: OtherLib
build-depends: base
hs-source-dirs: src
default-language: Haskell2010
executable mp-cabal
main-is: Main.hs
build-depends: base, mp-cabal
default-language: Haskell2010
Main.hs
module Main where
import MyLib
import OtherLib
main :: IO ()
main = do
print foo
print bar
MyLib.hs
module MyLib (foo) where
foo :: Integer
foo = 3
OtherLib.hs
module OtherLib where
bar :: Integer
bar = 4
Opening Main.hs
will result in an error. However, opening the library afterwards, will resolve the error.
If you open the library first and then the executable, no error will be shown at all, but if you try to compile it via cabal build
, there will be errors such as:
Main.hs:4:1: error:
Could not load module ‘OtherLib’
it is a hidden module in the package ‘mp-cabal-0.1.0.0’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
4 | import OtherLib
| ^^^^^^^^^^^^^^^
This makes perfect sense, if you consider how multiple components loading is implemented: Essentially we act like it is one big package. Ghci has no notion of private modules, afaict, and it had not reason to until now.
I expect to run into this problem as well when implementing support for multiple home units in GHC (https://gitlab.haskell.org/ghc/ghc/-/merge_requests/935/diffs#dbce6cb5e8f3d5287103c66d1a56ad63bbbd11a9) where we also don't have a notion of private modules when loading a unit.
What could be a possible solution to this problem? We could teach GHCi about private modules that can not be imported by other units. Would this break any abstractions?