Haskell: same module found twice - "Ambiguous module name" - haskell

I have the following import in a haskell file. I'm using cabal.
import Network.Wai (Application, Response, rawPathInfo, responseFile, responseLBS, requestBody)
But I'm getting this error when I try to build the file:
Error: Ambiguous module name ‘Network.Wai’:
it was found in multiple packages: wai-3.2.2.1 wai-3.2.2.1
Note that the multiple packages are exactly the same. Something like -XPackageImports doesn't work here, because for some reason the same package is installed twice.
I opened up /Users/<user>/.cabal/store/ghc-8.6.5/package.db and sure enough, there were two "w" (wai) packages with the same version but different hashes. I deleted one and this didn't fix it.

Related

How to import python git repos as packages

I am having trouble with importing python modules from two git repos as the code was not designed as a package, and there are name collisions which disabled me from being able to use sys.path.append in a straight-forward (albeit hacky?) manner.
Note that the problem is not particular of git-repos however I have encountered this problem only in this scenario because of trying to interface with existing work.
The folder structure looks like following:
project
- repo1
- foo.py
- bar.py
- run.py
- repo2
- foo.py
- bar.py
- run.py
test.py
Both foo.py import bar.py with import bar statements, which works fine as long as you are running the run.py scripts in the repo, however if I try to import repo1.foo and repo2.foo I run into multiple issues.
On attempting the following code
# test.py
import repo1.foo
import repo2.foo
I get the error ModuleNotFoundError: No module named 'bar', this makes some sense as nothing in the path makes either bar.py accessible.
However if I try to append paths 'repo1' and 'repo2' then I can only import either repo1.bar or repo2.bar depending on order of appends, which is not an acceptable solution.
As the repositories are not my code I would prefer to not change them, but instead wrap them into a namespaced package if possible, however I am unable to find any solutions for the problem.
TL;DR
Update:: As I was depending on this work extensively I published it as a Python package available here: https://pypi.org/project/packagify/ . You can install it instead of copying the old gist.
Add the class from this gist: https://gist.github.com/rijulg/3ea372bef35adb68e27080c949c942af in your code and you can use it as following
from packagify import Packagify
package = Packagify("/home/workspace/my_package")
object = package.import_module("module", ["object"])
object1, object2 = package.import_module("module", ["object1", "object2"])
Methods Tried
Installing the directory as a module using setuptools, this did not work as on loading the module various parts inside it threw ModuleNotFoundError as they were trying to access siblings without namespaces.
Various importlib functions, there are a few that allow loading python modules from .py files directly. This might have worked if the modules I wanted to import were contained within a file, but then perhaps there would be other solutions as well. As the problem stood I wasn't able to use this method as the module upon loading wasn't able to locate it's siblings.
Adding sys.path as mentioned in the question, but I also tried appending the path, loading module and then removing the path before loading the other module. This also did not work because presumably the modules were loaded into python cache and subsequent loads from different directory were ignored because of name clashes.
Finally, I noticed something weird happening when I changed the import level using the __import__ function and I tried the following snippet which worked fine on my toy example. However this still had various issues that I encountered while trying to load the actual repos I wanted to work with. As the solution appeared to be going in the right direction I made the class linked in the gist mentioned a the beginning of the post.
import builtins
original_import = __import__
def my_import(name, globals, locals, fromlist, level):
print("my_import", name, globals['__package__'], level)
try:
return original_import(name, globals, locals, fromlist, level)
except:
level = level + 1 if globals['__package__'] is not None else level
return original_import(name, globals, locals, fromlist, level)
builtins.__import__ = my_import
from repo1.foo import main as main_a
from repo2.foo import main as main_b
main_a()
main_b()

Haskell module import path navigation

I have a directory structure which goes something like this
a
- a.hs
- b
-- b.hs
- c
-- c.hs
I want to import c.hs in to b.hs but I can't work out how to go up a directory and in to b. Typically this would be something like ../c/c.hs.
What is the Haskell way to do this?
Typically you don't save "just code" but modules module ModuleName where. Modules are saved under a file name and path that reflects the module name so you'd have file ADirectory/A.hs (note the capital letter at the start) which starts with module ADirectory.A where and same with the others.
After writing your code people collect the modules into the package.
Sometimes off-handedly called "cabalization" due to using the cabal-install tool (or the alternative, stack), this can be done with cabal init and making sure your cabal file lists each module.
Inside modules such as the file ADirectory/A.hs, you can import the other modules. For example A can import B via import BDirectory.B.
Finally, if it isn't already obvious, the import statements refer to modules which the compiler must already have installed. It isn't possible to import something based on a file system path.

Haskell Import MissingH

I'm trying to import the Data.String.Utils module in my Haskell code, this is part of the MissingH package. I've installed cabal and used it to acquire MissingH, which is properly installed. However, wehn I try adding
import Data.String.Utils
to my code, WinHugs returns
ERROR file:.\ex.hs - Can't find imported module "Data.String.Utils"
Any feedback?
You already have MissingH installed with Cabal.
Using Cabal packages with WinHugs is hit and miss.
Use ghci and import Data.String.Utils should work.

Anyone having trouble install Control.Pipe?

I have the current version of cabal and running cabal install Pipe gave me no issues. But I tried these two imports:
import Control.Proxy
import Control.Pipe
But I'm getting this error message:
Could not find module `Control.Pipe'
It is not a module in the current program, or in any known package.
And the same for Proxy.
Any ideas?
It looks like you have installed Pipe. You probably meant to install pipes.

Could not find module, it is a member of the hidden package haskell98

When I try to compile a simple source file with import IO or import Random, the build fails with an error message like this:
Could not find module 'IO'
It is a member of the hidden package 'haskell98-2.0.0.1'
Use -v to see a list of the files searched for
The module names changed at some point. You probably want import System.IO and import System.Random instead.
Here is the module hierarchy for the standard libraries in GHC 7.6.1.

Resources