Ambiguous module name `Prelude' - haskell

I get this when i want to recompile xmonad to change the configuration:
Implicit import declaration:
Ambiguous module name `Prelude':
it was found in multiple packages: base haskell98-2.0.0.0
Xmonad was installed via pacman. When i got this error i removed xmonad from pacman and then tried to cabal install xmonad. I got the above error again but i was able to solve it by removing haskell98 from the cabal file.
Now i want to reconfigure xmonad with MOD-Q the error reappears and i have no clue how to fix this. Any help appreciated.
I use GHC version 7.0.3 (from Haskell platform)

Try this:
ghc-pkg hide haskell98

In my case hiding haskell98 unfortunately was insufficient, I had to remove the obsolete haskell98 from the build-depends list in my .cabal build file (keeping the base >= 4 of course).
It read before:
build-depends:
base >= 4,
haskell98
... and then ...
build-depends:
base >= 4
With that the error message "Ambiguous module name `Prelude'" above disappeared.

See this GHC bug ticket on the same subject:
GHC starting with version 7.2.1 will not support using the haskell98
package and the base package at the same time. The haskell-src package
has both of these in its build-depends, so it will need to be
modified. Most of the time, what you want to do is remove haskell98
from build-depends, and fix up any imports of Haskell 98 modules to
point to their base equivalents.
The bug ticket was closed (without a fix), and the original filer responded:
Yes, removing haskell98 from .cabal file seems to have fixed it - it
did compile without errors. It looks like it didn't have any imports
to haskell98, because according to comment in .cabal file.

Related

How do you import a Haskell module that was installed using Cabal?

I installed the timezone-series Haskell module using cabal install timezone-series-0.1.5.1.
I then defined a module named Main.hs that starts with:
import Data.Time.LocalTime.TimeZone.Series -- from timezone-series-0.1.5.1
when I run ghc Main.hs, GHC throws the following error:
/home/ubuntu/Main.hs:2:1: error:
Failed to load interface for ‘Data.Time.LocalTime.TimeZone.Olson’
I tried explicitly including the cabal directory in GHC's search path using:
ghc -i/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/ Main.hs
This resulted in the correct path being searched, but GHC is only looking for files ending in the suffix ".hs":
Locations searched:
...
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.hs
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.lhs
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.hsig
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.lhsig
Cabal installed interface files instead however:
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Olson.hi
From line 318 of GHC's source code it looks like GHC ignores "*.hi" files unless it is called in single-shot mode (with the -c flag). Is this correct? (See: https://github.com/ghc/ghc/blob/67a5a91ef5e61f3b3c84481d8a396ed48cd5d96e/compiler/GHC/Unit/Finder.hs)
How can I get GHC to import this module?
An help will be greatly appreciated!
My suggested ways of installing packages in order of my preference:
Make a cabal package and add timezone-series you want to install to the build-depends field as described in the cabal manual.
Use the experimental cabal-env tool to basically automate the process of point 3 below, but then with the global environment. This makes a new build-plan every time you install a new package, so it is like removing the package environment and building it again with all the old packages and the new package added to it. You can add specific constraints like this: cabal-env "timezone-series == 0.1.5.1".
Install a package into local package environment with cabal --package-env . --lib timezone-series. You can add as many packages as you want after the --lib option to install more than one package. If you later want to use a different set of packages simply remove the .ghc.environment.* file that is generated and rerun the installation with a new set of packages. GHC will automatically use these package environment files that are in the current or parent directories. You can specify specific constraints with the --constraint option like this: --constraint "timezone-series == 0.1.5.1".
Use cabal install --lib timezone-series to install it directly into the global environment (~/.ghc/x86_64-linux-8.0.2/environments/default), this will fail if a conflicting package was installed earlier. When you run into errors you can remove that package environment and try again.
Finally, I want to note that GHC 8.0.2 is quite old, so I would advise you to upgrade if you don't have a specific reason for using that version.

What should I do if two modules share the same name?

I have two packages that provide modules with the same name. When I try to load the module I get an error
Ambiguous interface for ....: It was found in multiple packages.
What should I do to resolve this?
To be specific, both the cryptonite package and crypto-api package provide modules with the name Crypto.Random. How can I specify which package I want to load the module from?
If you happen to be using ghc >= 8.2 and cabal-install >= 2.0, another option is renaming the conflicting modules in the mixins section of the cabal file:
build-depends: base >=4.10 && <4.11,
cryptonite >= 0.24,
crypto-api >= 0.13.2
mixins:
cryptonite (Crypto.Random as CryptoniteCrypto.Random),
crypto-api (Crypto.Random as CryptoAPICrypto.Random)
You can then import the renamed modules:
module Main where
import CryptoniteCrypto.Random
import CryptoAPICrypto.Random
One thing to take into account when renaming this way is that modules that haven't been explicitly renamed become inaccessible.
In fact, ability to rename modules seems to exist since GHC 7.10, through the -package flag and the reexported-modules cabal section. reexported-modules works at declaration-time (when publishing a package) while mixins works at use-time (when depending on a package).
You can use the PackageImports language pragma and explicitly pick the package you mean in your import statement like so:
import "cryptonite" Crypto.Random
Alternatively if you have both installed but are only using one of them, you could explicitly list the dependencies you use in a cabal file and build via cabal.

GHC can not find installed module

My haskell installation can not find bytestring module installed by operating system
$ ghci
GHCi, version 7.6.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.
Prelude> :m +Data.ByteString.Lazy
<no location info>:
Could not find module `Data.ByteString.Lazy'
It is not a module in the current program, or in any known package.
But I have installed this module using yum:
$ rpm -ql ghc-bytestring
/usr/lib64/ghc-7.6.3/bytestring-0.10.0.2
/usr/lib64/ghc-7.6.3/bytestring-0.10.0.2/libHSbytestring-0.10.0.2-ghc7.6.3.so
/usr/share/doc/ghc-bytestring
/usr/share/doc/ghc-bytestring/LICENSE
What is wrong?
If this is happening, you should be able to figure out more via ghc-pkg list. This could happen, for example, if the binary package provided by your software repository was broken; ghc-pkg list would report that. In general, either GHC is not looking for packages in /usr/lib64/ghc-7.6.3/ or else that directory has a package.cache which was not updated to reflect the new package.
One thing that could cause GHC to look in the wrong place is if there are multiple GHCs on the machine: for example if which ghc reveals /usr/local/bin/ghc then you probably compiled GHC from source at some point and its packages are occupying some /usr/local/lib/ghc-7.6.3/package.conf.d/ folder, while your repository has installed /usr/bin/ghc which is looking in the folder you want.
Anyway, fixes: if the package.cache file exists and has a valid entry for the file, then you can run ghc -package-conf /path/to/package.cache ... to add those packages to your executable. If you have further problems, ghc -v ... is a great resource for debugging "which version of that package is being used here?" types of problems.
If the package.cache file does not exist then you've got a bigger problem, and probably the easiest way to move forward is to look for a directory under /home which appears on ghc-pkg list. Install the required package to that directory and GHC should pick up on it even though it doesn't understand these bigger contexts. You could also start working with a cabal sandbox of local packages to your project.
Situation here is similiar to C++ you have libraries used during dynamic linking stage and header used for compilation. In Fedora packages like ghc-bytestring are only libraries without headers. To install headers I had to install ghc-bytestring-devel package.
An example on Fedora 24:
server.hs:7:8:
Could not find module ‘Data.Text’
Perhaps you meant Data.Set (from containers-0.5.5.1)
Locations searched:
Data/Text.hs
Data/Text.lhs
So change to user root, then:
What packages are there?
# dnf search ghc|grep text
ghc-text.x86_64 : An efficient packed Unicode text type
ghc-boxes.x86_64 : 2D text pretty-printing library
ghc-pango.x86_64 : Binding to the Pango text rendering engine
ghc-css-text.x86_64 : CSS parser and renderer
ghc-hgettext.x86_64 : Haskell binding to libintl
ghc-attoparsec.x86_64 : Fast combinator parsing for bytestrings and text
ghc-text-devel.x86_64 : Haskell text library development files
ghc-blaze-textual.x86_64 : Fast rendering of common datatypes
ghc-css-text-devel.x86_64 : Haskell css-text library development files
ghc-hgettext-devel.x86_64 : Haskell hgettext library development files
ghc-blaze-textual-devel.x86_64 : Haskell blaze-textual library development files
So what's installed?
# rpm --query ghc-text
ghc-text-1.1.1.3-3.fc24.x86_64
# rpm --query ghc-text-devel
package ghc-text-devel is not installed
So let's install the devel package.
# dnf install ghc-text-devel
Installed:
ghc-text-devel.x86_64 1.1.1.3-3.fc24
...and compilation succeeds after that.

Is there any way to define flags for cabal dependencies?

I recently ran into a Cabal issue that I only managed to solve by manually installing transformers-compat with the -f transformers3 flag in my cabal sandbox before running cabal install for my project.
Is there any way to indicate in my application's .cabal file that I depend on a library so that it is built with the specific build flag?
Newer versions of Cabal let you specify constraints in your cabal.project.local or cabal.project file. For example:
constraints: hmatrix +openblas
Is there any way to indicate in my application's .cabal file that I depend on a library so that it is built with the specific build flag?
No, but in your case this is not actually a problem in the solver and is rather and uninformative error (caused by someone's less than judicious uses of flags).
Looks like it's not possible to specify such a dependency via the build-depends field in your .cabal file. buildDepends is defined as [Dependency], where data Dependency = Dependency PackageName VersionRange. You can use cabal install --constraint="transformers-compat +transformers3", though.
Looking at the transformers-compat.cabal file, I think that the solver should be able to figure out the correct flag assignment if you constrain your dependency on transformers appropriately. E.g. build-depends: transformers >= 0.3 && < 0.4 should force the solver to choose transformers-compat +transformers3. If this doesn't work, it may be a bug in the solver.
I also struggled for a long time to find a solution to this problem. I just found one! You have to modify the global cabal configuration file at ~/.cabal/config. Add a constraints line like this to the initial section of the file:
constraints: hmatrix +openblas
This enables the openblas flag for the hmatrix package. It will be used automatically the next time the package is installed. If there is a way to set such a flag locally for a sandbox, I could not find it.
You cannot do this with Cabal.
One way to do this is to use Stack. Edit your stack.yaml to include
flags:
transformers-compat:
transformers3: true
See also the section on flags.
cabal now supports an elegant way to do this similar to stack, through cabal.project configuration options.
package transformers-compat
flags: +transformers3
will add the flag transformers3 when building the package transformers-compat.
There are a couple of ways to constrain the version for installation.
Add lower and upper bounds to package versions in the cabal file like Mikhail mentioned above, example of such a file here
Additionally, you can override the settings in the .cabal file with the flag cabal install --constraint="bar-2.1"
To remove a specific version of a package:
In a sandbox you can unregister a version with cabal sandbox hc-pkg unregister bar-2.1
Global unregistering can be done with this command outside of sandbox ghc-pkg unregister bar-2.1

Control.Monad.State found in multiple packages haskell

While evaluating the line "import Control.Monad.State" in a Haskell module, GHC gives me the following error:
Could not find module `Control.Monad.State':
it was found in multiple packages: monads-fd-0.0.0.1 mtl-1.1.0.2
Failed, modules loaded: none.
How do I resolve this conflict?
You have several options. Either:
ghc-pkg hide monads-fd. This will cause GHC and GHCi to ignore the presence of the monads-fd by default until you later ghc-pkg expose monads-fd, but software installed by Cabal will still be able to build against it.
Use the {-# LANGUAGE PackageImports #-} pragma, and change your import statement to import "mtl" Control.Monad.State.
Use Cabal to build your project, and specify mtl in the Build-depends line.
The first is best for casual hacking, and the last is best for production builds.
These all assume you want the mtl module and not the monads-fd module; otherwise swap them.
Both packages implement Control.Monad.State and GHC does not know which implementation it should prefer, so you need to hide one of the packages from GHC. Seems like the -ignore-package <name> GHC flag might help you here.

Resources