How to install and import a library in haskell? - haskell

In official tutorial Haskell in 5 steps, an example imports a library:
import Control.Parallel
Then I use ghc to compile:
ghc parallel.hs -o parallel -O2 --make -threaded -rtsopts
just as the tutorial tells me to do. (My filename is parallel.hs) But I got:
parallel.hs:1:1: error:
Could not find module ‘Control.Parallel’
Use -v to see a list of the files searched for.
|
1 | import Control.Parallel
| ^^^^^^^^^^^^^^^^^^^^^^^
Then I stackoverflowed it and find this question. So I:
cabal new-install parallel --lib
And get:
Resolving dependencies...
Up to date
Then I compiled it again, but got the same error.
How to solve this? Did I miss any command line arguments?
Well, after cabal install parallel, the library is imported, the program is compiled successfully, and runs as expected.
I'll refer to documentations of cabal about the difference between install and new-install

As #Lorenzo noted, cabal install works fine. With cabal new-install you should have seen a warning that you forgot --lib since parallel does not include an executable and libraries must be explicitly installed via --lib. The full set of functional commands are:
cd $(mktemp -d)
cabal update && cabal new-install --lib parallel
cat <<EOF > parallel.hs
module P where
import Control.Parallel
EOF
ghc -c parallel.hs
ls parallel.o parallel.hi
Yielding:
% cd $(mktemp -d)
% cabal update && cabal new-install --lib parallel
... snipped output ...
% cat <<EOF > parallel.hs
module P where
import Control.Parallel
EOF
% ghc -c parallel.hs
Loaded package environment from /home/tommd/.ghc/x86_64-linux-8.6.4/environments/default
% ls parallel.o parallel.hi
parallel.hi parallel.o

Related

How to run shake without stack

I created the recommended build.sh file from the "Running" section of the Shake manual:
#!/bin/sh
mkdir -p _shake
ghc --make Shakefile.hs -v -rtsopts -threaded -with-rtsopts=-I0 -outputdir=_shake -o _shake/build && _shake/build "$#"
but running that script gives the following error:
[1 of 1] Compiling Main ( Shakefile.hs, _shake/Main.o )
Shakefile.hs:1:1: error:
Could not find module ‘Development.Shake’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
1 | import Development.Shake
| ^^^^^^^^^^^^^^^^^^^^^^^^
Shakefile.hs:2:1: error:
Could not find module ‘Development.Shake.Command’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
2 | import Development.Shake.Command
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Shakefile.hs:3:1: error:
Could not find module ‘Development.Shake.FilePath’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
3 | import Development.Shake.FilePath
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Shakefile.hs:4:1: error:
Could not find module ‘Development.Shake.Util’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
4 | import Development.Shake.Util
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I did cabal v2-install shake --installpath=bin, but still get the same error afterwards. I also tried bin/shake but get the same error.
I tried adding -package shake to the ghc command in the build.sh, but get this error:
<command line>: cannot satisfy -package shake
(use -v for more information)
Adding -v as suggested gives this error:
Glasgow Haskell Compiler, Version 8.8.4, stage 2 booted by GHC version 8.8.3
Using binary package database: /Users/avh4/.ghcup/ghc/8.8.4/lib/ghc-8.8.4/package.conf.d/package.cache
package flags [-package shake{package shake True ([])}]
loading package database /Users/avh4/.ghcup/ghc/8.8.4/lib/ghc-8.8.4/package.conf.d
<command line>: cannot satisfy -package shake
(use -v for more information)
What is the correct way to use Shake without Haskell stack (preferably using only ghc 8.8 installed with ghcup and/or with cabal-install v2 commands)?
I figured out I need to use the --lib flag with cabal new-install otherwise only the shake binary gets installed.
After running cabal new-install --lib shake, the original build.sh script with the addition of -package shake to the ghc arguments now works! And runhaskell -package shake Shakefile.hs also works now.

How to work together with cabal-3 and ghc (ghc-pkg, too)?

With the release of cabal-3, the packages from Hackage are installed in a new location that the compiler ghc and ghc-pkg know nothing about.
In other words, packages are installed but not registered for ghc. Ghci, ghc, ghc-pkg cannot work.
For example,
cabal install safe --lib
Create file t1.hs
import Safe
t1 = tailMay [1,2,3]
Let's try:
> ghci t1.hs
GHCi, version 8.10.2: https://www.haskell.org/ghc/:? for help
[1 of 1] Compiling Main (t1.hs, interpreted)
t1.hs: 1: 1: error:
Could not find module `Safe '
Use -v (or `: set -v` in ghci) to see a list of the files searched for.
|
1 | import Safe
| ^^^^^^^^^^^
Failed, no modules loaded.
This bug is described here
https://github.com/haskell/cabal/issues/6262
and here
https://gitlab.haskell.org/ghc/ghc/-/issues/17341
I use as a temporary solution setting a system variable
GHC_PACKAGE_PATH=C:\Users\me\AppData\Roaming\cabal\store\ghc-8.10.2\package.db;
(Windwos 10, haskell-dev by chocolatey)
via
On Windows, packages installed with cabal seem to be unavailable in ghc/ghci
but with updates I will have to manually change this system variable.
Are there any more elegant solutions to this problem?
P.S. Unfortunately, this solution (via GHC's environment variable GHC_PACKAGE_PATH) is incompatible with Cabal :(
https://github.com/haskell/cabal/issues/1944
One way to achieve this is to use the --env flag to make the libraries available to GHC whenever you are in the current directory:
~ $ mkdir /tmp/foo
~ $ cd /tmp/foo
/tmp/foo $ cabal install safe --lib --env .
Resolving dependencies...
Build profile: -w ghc-8.8.3 -O1
In order, the following will be built (use -v for more details):
- safe-0.3.19 (lib) (requires build)
Configuring library for safe-0.3.19..
Preprocessing library for safe-0.3.19..
Building library for safe-0.3.19..
…
> Installing library in /home/jojo/.cabal/store/ghc-8.8.3/incoming/new-4056/home/jojo/.cabal/store/ghc-8.8.3/safe-0.3.19-92fbaef88124b4508ce447f6245bc793f7a1748247ae68d10e449150df1069af/lib
t1.hs
/tmp/foo $ cat > t1.hs
import Safe
t1 = tailMay [1,2,3]
/tmp/foo $ ls -a
. .. .ghc.environment.x86_64-linux-8.8.3 t1.hs
/tmp/foo $ ghci t1.hs
GHCi, version 8.8.3: https://www.haskell.org/ghc/ :? for help
Loaded package environment from /tmp/foo/.ghc.environment.x86_64-linux-8.8.3
[1 of 1] Compiling Main ( t1.hs, interpreted )
Ok, one module loaded.
*Main>
Note that you probably shouldn’t do this in a directory where you actually have a foo.cabal file. See the documentation of cabal v2-install for details.
Working with GHC_ENVIRONMENT is better:
setx GHC_ENVIRONMENT C:\Users\me\.ghc\x86_64-mingw32-8.10.2\environments\default
it helps for ghc and ghci.
After, in C:\Users\me\AppData\Roaming\cabal\config we should add
package-db: C:\Users\me\AppData\Roaming\cabal\store\ghc-8.10.2\package.db
it helps for cabal.
Unfortunately, ghc-pkg still has problem and works with such flag:
ghc-pkg list --user-package-db="C:\Users\me\AppData\Roaming\cabal\store\ghc-8.10.2\package.db"
For Linux the steps are similar.

How to use Text.Parsec in GHC-8.2.2 and Cabal-2.0.0.1

As I know Text.ParserCombinators.Parsec is replaced by Text.Parsec
Here, it is my environment
4.9.73-1-MANJARO
The Glorious Glasgow Haskell Compilation System, version 8.2.2
cabal-install version 2.0.0.1
compiled using version 2.0.1.0 of the Cabal library
The following source code is my main.hs
module Main where
import System.Environment
import Text.Parsec
main :: IO ()
main = do
args <- getArgs
putStrLn (readExpr (args !! 0))
and then I compile it
$ ghc -package parsec -o main main.hs
It occurs the following error messages
[1 of 1] Compiling Main ( main.hs, main.o )
main.hs:3:1: error:
Could not find module ‘Text.Parsec’
There are files missing in the ‘parsec-3.1.11’ package,
try running 'ghc-pkg check'.
Use -v to see a list of the files searched for.
|
3 | import Text.Parsec
| ^^^^^^^^^^^^^^^^^^
rm: cannot remove '*.hi': No such file or directory
./run.sh: line 11: ./TestProj: No such file or directory
I make sure I have installed parsec. So I want to ask any mistake I've done?
$ cabal install parsec
Resolving dependencies...
All the requested packages are already installed:
parsec-3.1.11
Use --reinstall if you want to reinstall anyway.
Manjaro might have inherited from Arch's issues with Haskell.
What is going on
Arch installs dynamic libraries, but ghc links statically by default. This is also what the error message "There are files missing in the ... package", indicating that the package exists but does not contain what ghc is looking for.
If I try compiling with the -v verbose flag on, the error message expands to:
ghc -v main.hs
(...)
Locations searched:
Text/Parsec.hs
Text/Parsec.lhs
Text/Parsec.hsig
Text/Parsec.lhsig
/usr/lib/ghc-8.2.2/site-local/parsec-3.1.11/Text/Parsec.hi
(...)
In particular, look into the last reported location, which may be different on your system; if my guess is correct, ghc is looking for a static interface file .hi as the message indicates but there is only a dynamic one .dyn_hi.
Fix
Compile with the -dynamic flag.
ghc -dynamic main.hs
And if that works read this to fix the setup:
https://wiki.archlinux.org/index.php/Haskell
You will have to choose between static and dynamic linking; I don't actually understand the trade-off here.

ghc-mod does not use my cabal sandbox. why?

runghc -package-db=.cabal-sandbox/.cabal-sandbox/x86_64-osx-ghc-7.8.3-packages.conf.d hellowai.hs
Works perfect for me.
Similarly, with
ghci -package-db=.cabal-sandbox/.cabal-sandbox/x86_64-osx-ghc-7.8.3-packages.conf.d
I am also able to import my cabal-sandbox-installed Wai package in ghci with no issue at all.
But when I ask ghc-mod to validate my haskell source code, via
ghc-mod check --boundary="" -g -package-db=.cabal-sandbox/x86_64-osx-ghc-7.8.3-packages.conf.d hellowai.hs
hellowai.hs:4:8:Could not find module ‘Network.Wai.Handler.Warp’Use -v to see a list of the files searched for.
hellowai.hs:3:8:Could not find module ‘Network.HTTP.Types’Perhaps you meant Network.HTTP.Base (from HTTP-4000.2.19) Network.HTTP.Base (needs flag -package HTTP-4000.2.10) Network.HTTP.Headers (needs flag -package HTTP-4000.2.10)Use -v to see a list of the files searched for.
hellowai.hs:2:8:Could not find module ‘Network.Wai’Perhaps you meant Network.BSD (needs flag -package network-2.4.2.3) Network.URI (needs flag -package network-2.4.2.3) Network.TCP (needs flag -package HTTP-4000.2.10)Use -v to see a list of the files searched for.
It is unable to find my cabal sandbox installed module. Why is that so?
Do you have a cabal.sandbox.config file? And are you using a .cabal file for your project?
If you have both of these you should be able to use ghc-mod check ... and it will just work.
Another advantage of using a .cabal file is that you can use cabal repl to invoke ghci and cabal run to invoke runhaskell with the correct command line options.
Update
Here is a recipe you can try out to see when ghc-mod can find your cabal sandbox. Perhaps this can help you determine what's different with your set up.
Start in a clean directory:
$ mkdir foo
$ cd foo
$ cabal sandbox init
$ cabal get split
$ cd split-0.2.2
$ cabal sandbox init --sandbox=../.cabal-sandbox
Edit around line 55 of split.cabal to add heredoc as a dependency.
Edit src/Data/List/Split.hs to use the module Text.Heredoc:
{-# LANGUAGE QuasiQuotes #-}
...
import Text.Heredoc
...
foo :: String
foo = [here|this is a test|]
Make sure heredoc is installed:
$ cabal install --only-dependencies
Finally this should work:
$ ghc-mod check ./src/Data/List/Split.hs
And it will still work if you cd into a sub-directory:
$ cd src
$ ghc-mod check ./Data/List/Split.hs
However, ghc-mod won't work if you move away split.cabal:
(back at the top level directory)
$ mv split.cabal split.cabal-old
$ ghc-mod check ./src/Data/List/Split.hs
In this case I created the sandbox in a parent directory of our working directory, but things should also work if the initial sandbox was created like this:
$ mkdir foo
$ cd foo
$ mkdir sandbox-dir
$ cd sandbox-dir
$ cabal sandbox init
$ cd ..
$ cabal get split
$ cd split-0.2.2
$ cabal sandbox init --sandbox=../sandbox-dir/.cabal-sandbox

cabal-dev install Happstack-server how

here is what I did:
makdir happstack_01
cabal-dev install happstack-server
write the typical helloworld.hs with "import Happstack.Server (nullConf, simpleHTTP, toResponse, ok)"
ghc -threaded HelloWorld.hs -o helloworld
and I got:
Could not find module `Happstack.Server'
This is so obvious wrong. But what I am more surprised is that no tutorial on google for simple thing as this.
Any intuition would be awesome!
This is a set of instructions for a very bare-bones, Cabalized, and sandboxed build.
$ mkdir happstack01 && cd happstack01/
$ cabal init .
$ <CR><CR><CR><CR><CR><CR><CR><CR><CR> 1 <CR><CR><CR>
$ mkdir src
$ touch src/Main.hs
$ vi happstack-01.cabal
In happstack01.cabal
...
library
exposed-modules:
Main
build-depends: base >=4.6 && <4.7
, happstack-server
hs-source-dirs: src
default-language: Haskell2010
Then
$ cabal sandbox init
$ cabal install --only-dependencies
$ vi src/Main.hs
In src/Main.hs
import Happstack.Server
main :: IO ()
main = simpleHTTP nullConf $ return "Hello sandbox!"
Get some coffee while the sandbox builds.
$ cabal repl
> main
After this I usually add an executable entry to the Cabal file and begin to build the server from that.
Since you wanted a small tutorial, I am writing up how I just got it to work. I used cabal instead of cabal-dev though (if you care, let me know and I can play around a bit more)....
> cabal install happstack-server
> mkdir sample
> cd sample
Then I created the file sample.hs
import Happstack.Server
main = simpleHTTP nullConf $ return "hello, world!"
and I compiled it
> ghc sample.hs
(This is where you seem to be having problems finding the library.... You might want to check if ~/.ghc//package.conf.d/happstack-server-7.3.1-.conf and ~/.cabal/packages/hackage.haskell.org/happstack-server/ exist to verify the download)
Then run the server
./sample
and verify that it works using curl
> curl http://127.0.0.1:8000
This should respond with
hello, world!
ok I figured this out. GHC will not regonized local sanboxed libs. at least my GHC --version 7.6.3 does not. So I will have to cabalise my project in order to make sandboxed libs work.

Resources