Cabal supports sublibraries, wherein you could specify multiple libraries to be built in addition to the main one (the one without a name) in the package.
Cabal also supports specifying the visibility of these sublibraries, public or private, which by default is “private.” (EDIT: it is private per doc.)
An example:
library lvm
import: basic-options
visibility: private
--
hs-source-dirs: ./internal/lvm
exposed-modules: ...
build-depends: ...
However, I recently learned that my default setup doesn’t jibe well with this setting. I am using haskell-language-server (HLS) 2.9.0.0 and Emacs 29.4. As far as I am aware, this tip should also apply to vscode + HLS too.
What I did to make my setup work better are:
cabal.project
multi-repl: true
–enable-multi-repl
Allow starting GHCi with multiple targets. This requires GHC with multiple home unit support (GHC-9.4+)
The closure of required components will be loaded.
emacs’s lsp-haskell configuration
(use-package haskell-mode
;; ...
:custom
(lsp-haskell-session-loading "multipleComponents")
;;
vscode HLS configuration
According to people using vscode, similarly, you should use:
haskell.sessionLoading: "multipleComponents"
I am not aware of the full story behind these settings, and I wonder if this option should become the default. But in any case, hope it can be helpful to you too.