How to import Control.Lens in Haskell? - haskell

I am new to Haskell. I want to use Control.Lens package. I've read this and applied what it says but I get an error that says:
Resolving dependencies...
cabal-3.6.2.0.exe: Cannot build the executables in the package lens because it
does not contain any executables. Check the .cabal file for the package and
make sure that it properly declares the components that you expect.
when I try to run cabal install lens in the project folder.(I opened terminal in the project folder.)
Any help would be appreciated.
Solution: I've learned that I need to add 'lens' into build-depends part of .cabal file.Then I need to import Control.Lens inside Main.hs . I give my .cabal file as an example:
executable Prelude3
main-is: Main.hs
-- Modules included in this executable, other than Main.
--other-modules: Basic
-- LANGUAGE extensions used by modules in this package.
-- other-extensions:
build-depends: containers,lens,microlens,microlens-platform,base ^>=4.14.3.0
hs-source-dirs: app
default-language: Haskell2010
On the top of the Main.hs I write import Control.Lens. Finally after I run 'cabal build' and cabal run in the terminal necessary packages successfully downlaoaded.

Related

Cabal install package in local directory not reflecting while importing in file

I am currently self studying Haskell. I am just a beginner so I haven't yet had a need to use cabal or stack. But right now I need to test some of my code using QuickCheck.
From this link that I found https://github.com/haskell/cabal/blob/master/doc/cabal-commands.rst , I ran the command cabal install --lib QuickCheck --package-env . and got the following output :
axiom#pop-os:~/Desktop/Haskell-Learning/Course/Homework 10$ cabal install --lib QuickCheck --package-env .
Resolving dependencies...
Up to date
In the same directory, I have a .hs file and in that when I tried to import Test.QuickCheck the linter gives an error as the package doesnt seem to be available for importing.
Then I ran cabal repl --build-depends QuickCheck and then in ghci I was able to import it. But still it was not importing in the code file.
Then when I just opened ghci by firing the command ghci , the following shows up, which suggests that there is a package environment here in this directory :
GHCi, version 8.10.7: [https://www.haskell.org/ghc/](https://www.haskell.org/ghc/) :? for help
Loaded package environment from /home/axiom/Desktop/Haskell-Learning/Course/Homework 10/.ghc.environment.x86\_64-linux-8.10.7
Prelude> import Test.QuickCheck
Prelude Test.QuickCheck> :q
Even after above, that is, being able to import QuickCheck in GHCi, the import is still not working in the file.
After this, I tried the following :
axiom#pop-os:~/Desktop/Haskell-Learning/Course/Homework 10$ cabal install QuickCheck
Resolving dependencies...
Up to date
Warning:
############################################################
# WARNING: Installation might not be completed as desired! #
############################################################
The command "cabal install [TARGETS]" doesn't expose libraries.
* You might have wanted to add them as dependencies to your package. In this
case add "QuickCheck" to the build-depends field(s) of your package's .cabal
file.
* You might have wanted to add them to a GHC environment. In this case use
"cabal install --lib QuickCheck". The "--lib" flag is provisional: see
https://github.com/haskell/cabal/issues/6481 for more information.
axiom#pop-os:~/Desktop/Haskell-Learning/Course/Homework 10$ cabal install --lib QuickCheck
Resolving dependencies...
Up to date
The import still doesn't work.
Any help is appreciated !
The method I ended up finding is the following :
Run the following in the directory where you have your haskell file where you want to import an external package :
cabal init
This will general a small number of files and such in that directory.
Add the name of the package that you want to use in the .cabal file that was generated . For example, I wanted to use QuickCheck so my .cabal file looks like this :
cabal-version: 2.4
name: Homework10
version: 0.1.0.0
author: Name Surname
maintainer: name#email.com
extra-source-files: CHANGELOG.md
executable Homework10
main-is: Main.hs
build-depends: base ^>=4.14.3.0, QuickCheck
hs-source-dirs: app
default-language: Haskell2010
Then in the same directory, run the following :
cabal build
Then when you try to import the package in your .hs, you should be able to do so.

Build dependency in library or executable section of cabal file?

First off, I'm new to using cabal and external packages with Haskell.
I'm trying to use the Graphics.Gloss package inside of MyLib. I can make it work if I include gloss in both the build-depends of library and executable.
Here is the relevant portion of the cabal file:
library
exposed-modules: MyLib
build-depends: base ^>=4.13.0.0,
gloss ^>=1.13.1.1
default-language: Haskell2010
executable ray-tracer
main-is: Main.hs
other-modules: MyLib
build-depends: base ^>=4.13.0.0, ray-tracer,
haskell-say ^>=1.0.0.0,
gloss ^>=1.13.1.1
MyLib.hs
module MyLib (someFunc) where
import Graphics.Gloss
someFunc :: IO ()
someFunc = display (InWindow "My Window" (200,200) (10,10)) white (Circle 80)
Main.hs
module Main where
import qualified MyLib (someFunc)
import HaskellSay (haskellSay)
main :: IO ()
main = do
MyLib.someFunc
Why doesn't this work when gloss is only included in the library dependencies?
You can make it work. There is a problem in your current set up, which is that the files for the library and the executable are in the same directory. See also this question How to avoid recompiling in this cabal file? which is a symptom of the same underlying problem: when you build the executable, it rebuilds MyLib from scratch (which requires the gloss dependency) instead of reusing your library that was already built.
MyLib/
ray-tracer.cabal
MyLib.hs
Main.hs # Bad
Move the .hs files in separate directories (technically you only need to move one of them, but I think it's better to keep the root directory as uniform as possible):
MyLib/
MyLib.cabal
src/
MyLib.hs
exe/
Main.hs
And in the cabal file, add hs-source-dirs: src and hs-source-dirs: exe to the corresponding sections:
library
hs-source-dirs: src
...
executable ray-tracer
hs-source-dirs: exe
...

How do I add the "containers" package to my .cabal file (without getting overwritten by stack at compile time)?

I am working on the "roman-numerals" task from the exercism Haskell track and followed their instructions to installing stack. I am working on a Fedora 24 box.
As long as I was working with Haskell modules from base, I didn't have a problem. Now I am trying to import the Data.Map module. It works fine using the ghci command line:
$ ghci
GHCi, version 7.8.4: 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> import Data.Map
Prelude Data.Map>
However, when I try to import it from inside my src file with the command:
import qualified Data.Map as M (foldlWithKey, fromList)
I am running into problems when I try to run the test:
$ stack test
roman-numerals-0.0.0: build (lib + test)
Preprocessing library roman-numerals-0.0.0...
[2 of 2] Compiling Roman (...)
(...) /roman-numerals/src/Roman.hs:3:1: error:
Failed to load interface for ‘Data.Map’
It is a member of the hidden package ‘containers-0.5.7.1’.
Perhaps you need to add ‘containers’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
Progress: 1/2
(...)
I googled the problem and found a straightforward solution at the Cabal FAQ at haskell.org:
What you need to do is to add containers to the build-depends in your .cabal file.
I am assuming they mean the file roman-numerals.cabal that is in my working directory. The contents are:
-- This file has been generated from package.yaml by hpack version 0.14.0.
--
-- see: https://github.com/sol/hpack
name: roman-numerals
version: 0.0.0
build-type: Simple
cabal-version: >= 1.10
library
hs-source-dirs:
src
build-depends:
base
exposed-modules:
Roman
other-modules:
Paths_roman_numerals
default-language: Haskell2010
test-suite test
type: exitcode-stdio-1.0
main-is: Tests.hs
hs-source-dirs:
test
build-depends:
base
, roman-numerals
, hspec
default-language: Haskell2010
I tried to add "containers" to the build-depends in either and both the "library" and "test-suite" sections, but when I run
$ stack test
the error persists, and the .cabal file is reverted to the same contents shown above.
Any pointers? Much appreciated!
This is hinting at the problem:
-- This file has been generated from package.yaml by hpack version 0.14.0.
--
-- see: https://github.com/sol/hpack
hpack is an alternative, YAML-based specification format for Haskell packages which can be used instead of the traditional cabal format. The hpack program can then be used to convert a specification from the hpack format to the cabal format to be able to integrate with the rest of the Haskell toolchain.
Some basic support for hpack was added to stack some time ago. It checks for a file called package.yaml in the current directory, which is the standard name for hpack format package specifications, and if it exists, it runs hpack to convert it to a cabal file and then proceeds building as normal. This is what's trampling over your .cabal file.
To solve this, either:
Modify package.yaml instead of roman-numerals.cabal to achieve the same effect.
Delete package.yaml and continue working directly with roman-numerals.cabal.
The syntax for adding dependencies in the hpack format is:
dependencies:
- base
- containers

Shared cabal "build-depends" (Haskell) [duplicate]

Here's a .cabal file:
Name: myprogram
Version: 0.1
-- blah blah blah
Cabal-version: >=1.9.2
Executable myprogram
HS-source-dirs: src
Main-is: Main.hs
Build-depends: attoparsec == 0.10.*,
base == 4.3.*,
-- long long list of packages
Test-Suite test
HS-source-dirs: test, src
Type: exitcode-stdio-1.0
Main-is: Main.hs
Build-depends: attoparsec == 0.10.*,
base == 4.3.*,
-- long long list of packages
QuickCheck == 2.4.*
Is there any way I can replace the long list of build-depends packages for the test suite with "same as for the executable, plus QuickCheck"?
Edit: version information.
cabal-dev 0.9
cabal-install 0.10.2
Cabal library 1.10.2.0
GHC 7.0.4
Haskell Platform 2011.4.0.0
NOTE: superseded by phadej's answer suggesting common stanzas.
Is there any way I can replace the long list of build-depends packages for the test suite with "same as for the executable, plus QuickCheck"?
Not that I know of. However, there is a way to only mention the list of build-depends packages once, by structuring your project into three targets:
a library that contains all your code, and needs the long build-depends list.
an executable that consists of only one file, and depends on base and the library from above.
a test-suite that depends on the library from above, and the testing packages you are using.
Maybe this approach is what indygemma's answer proposes, but the Cabal file proposed there will not quite achieve it, as Norman Ramsey points out in a comment. Here's the main points of what you need in a Cabal file. For a full example that works for me, you can look at this Cabal file.
name: my-program
version: ...
library
hs-source-dirs: src-lib
build-depends: base, containers, ...
exposed-modules: My.Program.Main, ...
executable my-program
hs-source-dirs: src-exec
main-is: my-program.hs
Build-depends: base, my-program
test-suite tests
type: exitcode-stdio-1.0
hs-source-dirs: src-test
main-is: tests.hs
other-modules: ...
build-depends: base, my-program, test-framework, ...
Important points:
There are three separate source directories for the three targets. This is necessary to stop GHC from recompiling library files when building the other targets.
All of the application code is in the library. The executable is just a wrapper, like this:
import My.Program.Main (realMain)
main = realMain
The library exposes all modules that are necessary for testing.
The last point highlights the drawback of this approach: You end up having to expose internal modules. The main benefit of this approach is that you have less duplication in the Cabal file, and maybe more importantly, less duplication in the build process: The library code will be built only once, and then linked into both the executable and the test-suite.
Since version 2.2 Cabal supports common stanzas, to dedup build info fields:
https://cabal.readthedocs.io/en/latest/developing-packages.html#common-stanzas
cabal-version: 2.2
name: myprogram
version: 0.1
-- blah blah blah
common deps
build-depends: base ^>= 4.11,
-- long long list of packages
ghc-options: -Wall
library
import: deps
exposed-modules: Foo
test-suite tests
import: deps
type: exitcode-stdio-1.0
main-is: Tests.hs
build-depends: foo
You could also consider using hpack instead of writing the .cabal file by hand:
In hpack's package.yaml format, you can specify a common dependencies field whose entries are added to every components' build-depends field when generating the .cabal file.
For example, see hpack's own package.yaml and the generated hpack.cabal.
To start using hpack with an existing package, you can use hpack-convert which will generate the package.yaml from an existing .cabal file.
To create a new package that uses hpack, you can use stack's simple-hpack template like so: stack new mypkg simple-hpack.
If you use stack for development, you don't have to call hpack manually to regenerate the .cabal file from an updated package.yaml – stack will do that automatically.
No easy way:
you can use m4 and specify your dependencies once, but then you will need to reprocess your Cabal file through m4 whenever you change it.
you can move the code you are testing out to a library, and then specify the library in your Build-depends for the test. That requires you to install a library even just to run the test.
You can just not put the test in the cabal file at all. Build it with ghc --make, which will pull in dependencies. But then you lose cabal integration.
There is an optional library section for .cabal files, which solves your problem.
name: myprogram
version: 0.1
-- blah blah blah
cabal-version: >=1.9.2
library
build-depends: attoparsec == 0.10.*
, base == 4.3.*
-- long long list of packages
executable myprogram
hs-source-dirs: src
main-is: Main.hs
test-suite test
hs-source-dirs: test, src
type: exitcode-stdio-1.0
main-is: Main.hs
build-depends: QuickCheck == 2.4.*

plugins package unknown symbol when using cabal

I'm messing around with the plugins package however I bumped into a problem.
Here's the code:
Util/Header.hs
module Util.Header(PT(..)) where
data PT a = PT a deriving Show
Plug.hs
module Plug(helloPlugin) where
import Util.Header
helloPlugin :: PT Int
helloPlugin = PT 1
Main.hs
module Main where
import Util.Header
import System.Plugins
main :: IO ()
main = do
mv <- load "Plug.o" ["."] [] "helloPlugin"
case mv of
LoadFailure msg -> print msg
LoadSuccess _ v -> print $ show (v :: PT Int)
This all works fine then compiling with ghc. Building with Cabal works fine as well, but when I run the executable I get this error:
plugintest: /home/kevin/.cabal/lib/plugins-1.5.4.0/ghc-7.6.3/HSplugins-1.5.4.0.o: unknown symbol `ghczm7zi6zi3_ErrUtils_zdsinsertzuzdsgo5_info'
plugintest: user error (resolvedObjs failed.)
My very minimalistic cabal file:
name: plugintest
version: 0.1.0.0
license-file: LICENSE
build-type: Simple
cabal-version: >=1.8
library
hs-source-dirs: src
exposed-modules: Util.Header
build-depends: base ==4.6.*, plugins ==1.5.*
executable plugintest
main-is: Main.hs
build-depends: base ==4.6.*, plugins ==1.5.*, plugintest == 0.1.0.0
hs-source-dirs: src
Now I assume the problem is that it can't find the "ErrUtils" module which is part of the ghc package installed in /usr/lib/ghc-7.x.x.
Since it's using cabal it'll use the $HOME/.cabal/lib/ instead.
Now I obviously wouldn't want to use /usr/lib if I wanted to make it distributable. Sadly I'm not very familiar with how packages are managed nor am I familiar with the plugins package.
I have a feeling this is extremly nooby but I wasn't able to find a solution myself.
So a few questions:
How can I get my dependencies to work in a way to make this distributable?
It seems I'll need to know beforehand what my Plugin.o files will depend on before actually being able to use them (If I understand correctly).
Is there a way to package a .o files that I wouldn't have to worry about this problem? (Sorry if this question is too vague, feel free to ignore)
Thanks in advance!
Ok, so I had the exact same problem.
Here is a workaround I found
Change the load call to
load "Plug.o" [".","dist/build/plugintest/plugintest-tmp"] [] "testplugin"
Make sure you compile the thing with -c or by using the "make" library from plugins.
Quite annoyed by this... The error suggests it is having issues linking against the standard libs, so why does showing it these .o files fix it?
Anyways, this worked for me, and didn't require a ton of mucking around with .cabal files.
You must declare your exported- and other- modules in order for Cabal to package them all together. For instance (from https://github.com/tel/happstack-heroku-test)
name: hktest -- note the name here names
-- the *library* which is a package name
-- in scope when building the executable
...
library
exposed-modules:
HKTest
other-modules:
-- there aren't any, but there could be some
build-depends: base >= 4.6 && <4.7
...
, mtl >= 2.1.2
hs-source-dirs: src
executable server
main-is: Server.hs
other-modules:
-- there might be some use to having these here,
-- but they'll be harder to get into GHCi, so I wouldn't
-- recommend it---just put them in the library part
build-depends: base >=4.6 && <4.7
, hktest -- note that I grab all the hktest
-- modules here
hs-source-dirs: exe
If I leave out one of those modules I'll likely get a build error as Cabal compiles files which expect to be able to find symbols that haven't been packaged.
In your case, since you're building an executable, the common pattern exemplified above is to put all of your code into a library and then have the executable side depend upon that library. For instance, in this example the complete text of exe/Server.hs is
module Main where
import qualified HKTest as HK
main :: IO ()
main = HK.main

Resources