gelisam / deploy-hint

Demonstrating that you don't need to install ghc in order to use the hint library.
11 stars 3 forks source link

other haskell libraries #6

Open polymorphicengine opened 3 years ago

polymorphicengine commented 3 years ago

I'm currently trying to reproduce a minimal working example with another haskell library than acme-dont. I have tried the following libraries: -tidal -mtl -clock I got it working only with Clock, but in all cases I did the same things:

I don't see why it's failing for mtl and tidal.

gelisam commented 3 years ago

Interesting, what's the error message? Perhaps acme-dont's lack of dependencies is an advantage; what if you also add transformers?

polymorphicengine commented 3 years ago

For example, when I try it with tidal, everything works fine and the tidal files are all there in root/my-program/haskell-libs, but if I try to import Sound.Tidal.Pattern with hint in the Main.hs, it throws the error

"WontCompile [GhcError {errMsg = ":\n Could not find module `Sound.Tidal.Pattern'\n Use -v to see a list of the files searched for."}]"

polymorphicengine commented 3 years ago

Just tried adding the transformers library and importing Control.Monad.Trans.Accum and it gives the following error:

Left (WontCompile [GhcError {errMsg = ":\n Could not find module `Control.Monad.Trans.Accum'\n Use -v to see a list of the files searched for."}])

gelisam commented 3 years ago

That means transformers and tidal are not in any of the package databases hint knows about. I would thus find the package database (some folder in which the binary artifacts are stored) in which they have been installed, and point hint to it. It mostly uses the same mechanisms as ghc (a -package-db command-line argument, the GHC_PACKAGE_PATH environment variable, a package environment file; see the ghc documentation for details) except the command-line arguments are passed as a list of strings to unsafeRunInterpreterWithArgs and friends.

Another approach would be to figure out what's the difference between clock and transformers, perhaps by creating a local package and gradually changing its definition from a copy of clock to a copy of transformers. Or maybe try a buch of other packages and hope to spot a pattern distinguishing those which work from those which don't.

gelisam commented 3 years ago

I took a closer look by running docker run -it with-ghc bash to start a shell on the VM which does have ghc installed, and it seems that transformers and acme-dont are indeed installed in different package databases:

mymachine $ docker run -it with-ghc bash
with-ghc # ghc-pkg --package-db=/opt/ghc/7.10.3/lib/ghc-7.10.3/package.conf.d --package-db=/root/.cabal-sandbox/x86_64-linux-ghc-7.10.3-packages.conf.d list 
/opt/ghc/7.10.3/lib/ghc-7.10.3/package.conf.d
   [...]
   base-4.8.2.0
   [...]
   transformers-0.4.2.0
   [...]
/root/.cabal-sandbox/x86_64-linux-ghc-7.10.3-packages.conf.d
   acme-dont-1.1
   [...]
   hint-0.5.2
   mtl-2.2.2
   [...]

and as a result, even on the machine on which ghc is installed, I still get Could not find module Control.Monad.Trans.Reader. I can get it to work using unsafeRunInterpreterWithArgs ["-package-db", "/opt/ghc/7.10.3/lib/ghc-7.10.3/package.conf.d", "-package-db", "/root/.cabal-sandbox/x86_64-linux-ghc-7.10.3-packages.conf.d"] (note: ghc-pkg's --package-db flag has two dashes, while ghc's -package-db flag has only one), but obviously that won't work on the machine on which ghc is not installed.

(btw this docker image uses a version of ghc which ships with a version of the transformers library which predates the addition of Control.Monad.Trans.Accum, so if you really need that module you'll need to update the script to more modern versions of hint and ghc)

The next step would be to tweak copy the files from the right package database. Notice how with-ghc.docker copies some of the packages from /opt/ghc/7.10.3/lib/ghc-7.10.3/package.conf.d/ and others from .cabal-sandbox/*-packages.conf.d; you need to be careful to copy each package from the right package database. The good news is that there is only a finite list of so-called "wired-in" packages, including transformers, which come with ghc and thus come from the /opt/ghc/7.10.3/lib/ghc-7.10.3/package.conf.d/ package database, every other package including tidal should come from .cabal-sandbox/*-packages.conf.d.

gelisam commented 3 years ago

I have pushed the branch https://github.com/gelisam/deploy-hint/tree/transformers to demonstrate that the approach works just fine with transformers, but since the existing acme-dont demo already uses many wired-in packages, I think the acme-dont demo is better since it also demonstrates how to support non-wired-in packages.

I am now back to my original guess that mtl and tidal were not working because their dependencies were not included; now that we know how to add mtl's transformers dependency, I bet mtl will work if we add both transformers and mtl to haskell-libs.

polymorphicengine commented 3 years ago

Thank you so much @gelisam ! I tried to get tidal working here: https://github.com/onthepeakofnormal/deploy-hint/tree/tidal. Imports of most of the libraries work. The only one I'm struggling with is semigroups (and the libraries that depend on it) and I don't really see why it's different. I can import all of it's dependencies without a problem, but not semigroups itself. What I also noticed is that I can import Numeric.Natural from the nats library, but there is no folder for it in .cabal-sandbox/lib/x86_64-linux-ghc-7.10.3/..

yaxu commented 3 years ago

Actually Tidal doesn't run on ghc versions prior to 8.x, due to a change to semigroups. I think if you switch to the latest ghc the problem with semigroups will go away.

gelisam commented 3 years ago

I can import Numeric.Natural from the nats library

Are you sure you're not actually importing the one from base?

polymorphicengine commented 3 years ago

Aha! No, then it is probably importing that one. I still don't get why there is no folder for nats in .cabal-sandbox/lib/x86_64-linux-ghc-7.10.3/

gelisam commented 3 years ago

maybe because its only module only re-exports a module from base and doesn't define anything new? In particular, while .cabal-sandbox/*-packages.conf.d/nats-*.conf does exist, that file doesn't have import-dirs and library-dirs entries pointing to that non-existing lib/nats* folder, while other packages to point to the corresponding lib folder.

gelisam commented 3 years ago

Taking a closer look at that file makes me realize that there is another family of folders which with-ghc.docker forgot to move:

/root/.cabal-sandbox/share/x86_64-linux-ghc-7.10.3/acme-dont-1.1

I assume that few packages make use of their data folder, but that we'll encounter problems once we encounter a package which does.

yaxu commented 3 years ago

We'll need a newer ghc, but will then have to get it working with the 'nix style builds' I think, as cabal sandbox was retired.