Cabal repl can't :load module in library - haskell

Hi I have the following modules in cabal file:
library task1-lib
exposed-modules:
Interpreter,
Parser
build-depends:
base ^>=4.14.3.0,
containers,
mtl,
parsec
ghc-options: -Wall -Werror -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates -Wno-unused-top-binds -Wno-orphans -Wno-type-defaults
hs-source-dirs:
task1/lib
default-language: Haskell2010
executable task1
main-is: Main.hs
ghc-options: -Wall -Werror -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates -Wno-unused-top-binds -Wno-orphans -Wno-type-defaults
build-depends:
base ^>=4.14.3.0
hs-source-dirs: task1
default-language: Haskell2010
When I do:
cabal repl
...
GHCi, version 8.10.7: https://www.haskell.org/ghc/ :? for help
[1 of 2] Compiling Interpreter ( task1/lib/Interpreter.hs, interpreted )
[2 of 2] Compiling Parser ( task1/lib/Parser.hs, interpreted )
Ok, two modules loaded.
> :l Parser
I get the following error:
<no location info>: error: [-Wmissing-home-modules, -Werror=missing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules:
Interpreter
Question
What to do when I want to load a single file to experiment with the functions from that module in repl?
Also when I try the command cabal repl task1-lib the same happens.
EDIT:
There is a possible workaround to modify the cabal in the following way, by adding the -Wwarn=missing-home-modules after the -Werror. This still applies the -Werror for all warnings instead of the missing-home-modules error that remains a warning and makes it possible to :load a module in repl then.
library task1-lib
exposed-modules:
Interpreter,
Parser
build-depends:
base ^>=4.14.3.0,
containers,
mtl,
parsec
ghc-options: -Wall -Werror -Wwarn=missing-home-modules -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates -Wno-unused-top-binds -Wno-orphans -Wno-type-defaults
hs-source-dirs:
task1/lib
default-language: Haskell2010
executable task1
main-is: Main.hs
ghc-options: -Wall -Werror -Wcompat -Widentities -Wincomplete-uni-patterns -Wincomplete-record-updates -Wno-unused-top-binds -Wno-orphans -Wno-type-defaults
build-depends:
base ^>=4.14.3.0
hs-source-dirs: task1
default-language: Haskell2010

import enables only functions that are exported by the module
Instead of unsing :load or import, try using :module + *NameOfTheModule.
According to the docs for :module:
:module supports the * modifier on modules, which opens the full
top-level scope of a module, rather than just its exports.
This can't be done with ordinary import declarations, which behave much like imports in regular Haskell programs.

Related

Stack auto-removes dependency from .cabal file following 'stack build'

I want to work on a new Haskell project using the threepenny-gui package.
The first thing I did was create a stack project via $ stack new threepennydemo. From here, here, I did the following:
I edited the extra-deps section in my stack.yaml file from:
# extra-deps: []
to
extra-deps:
- threepenny-gui-0.9.0.0
I edited the .cabal file from:
library
exposed-modules:
Lib
other-modules:
Paths_threepennydemo
hs-source-dirs:
src
build-depends:
base >=4.7 && <5
default-language: Haskell2010
executable threepennydemo-exe
main-is: Main.hs
other-modules:
Paths_threepennydemo
hs-source-dirs:
app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
, threepennydemo
default-language: Haskell2010
test-suite threepennydemo-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Paths_threepennydemo
hs-source-dirs:
test
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
, threepennydemo
default-language: Haskell2010
to
library
exposed-modules:
Lib
other-modules:
Paths_threepennydemo
hs-source-dirs:
src
build-depends:
base >=4.7 && <5
, threepenny-gui >= 0.9
default-language: Haskell2010
executable threepennydemo-exe
main-is: Main.hs
other-modules:
Paths_threepennydemo
hs-source-dirs:
app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
, threepennydemo
, threepenny-gui >= 0.9
default-language: Haskell2010
test-suite threepennydemo-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Paths_threepennydemo
hs-source-dirs:
test
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
, threepennydemo
, threepenny-gui >= 0.9
default-language: Haskell2010
I edited the stock /app/Main.hs from:
module Main where
import Lib
main :: IO ()
main = someFunc
to
import Graphics.UI.Threepenny
main :: IO ()
main = do
startGUI defaultConfig showMessage
showMessage :: Window -> UI ()
showMessage window = do
getBody window #+ [string "Hello, world!"]
return ()
I enter the command $ stack build.
From here, I notice two things. The first is that I receive the following error:
Building all executables for `threepennydemo' once. After a successful build of all of them, only specified executables will be rebuilt.
threepennydemo> configure (lib + exe)
Configuring threepennydemo-0.1.0.0...
threepennydemo> build (lib + exe)
Preprocessing library for threepennydemo-0.1.0.0..
Building library for threepennydemo-0.1.0.0..
Preprocessing executable 'threepennydemo-exe' for threepennydemo-0.1.0.0..
Building executable 'threepennydemo-exe' for threepennydemo-0.1.0.0..
[1 of 2] Compiling Main
/Users/my_username/threepennydemo/app/Main.hs:1:1: error:
Could not load module ‘Graphics.UI.Threepenny’
It is a member of the hidden package ‘threepenny-gui-0.9.0.0’.
Perhaps you need to add ‘threepenny-gui’ to the build-depends in your .cabal file.
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
1 | import Graphics.UI.Threepenny
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-- While building package threepennydemo-0.1.0.0 using:
/Users/my_username/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.4 --builddir=.stack-work/dist/x86_64-osx/Cabal-3.0.1.0 build lib:threepennydemo exe:threepennydemo-exe --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
The second is that my .cabal file, edited as mentioned in 2., has automatically removed the edits I made to the file.
What am I missing in order to be able to use a third party library when setting up a new stack project?
My difficulty as the result of some confusion between stack.yaml and package.yaml. The latter being what generates the threepennydemo.cabal file. Hence, dependencies must also be specified to a package.yaml file. Adding this dependency to the package.yaml allowed $ stack build to complete without issue.

Two executables in one cabal file; stack build does not recognize them

I'm trying to make 2 executables "project". All duplicates of this question did not help me - their answers don't fix my problem. I have .cabal file like this:
name: int-tests
version: 0.1.0.0
synopsis: Integration Tests Suite
description: Integration Tests Suite
license: AllRightsReserved
author: Author name here
maintainer: example#example.com
copyright: 2018 Author name here
build-type: Custom
extra-source-files: README.md
cabal-version: >=1.10
library
hs-source-dirs: common
exposed-modules: Common
build-depends: base
, text
, aeson
, network-uri
default-language: Haskell2010
ghc-options: -Wall -Werror
executable api-tests-exe
hs-source-dirs: api
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Werror
build-depends: base
, hspec
, QuickCheck
default-language: Haskell2010
executable e2e-tests-exe
hs-source-dirs: e2e
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Werror
build-depends: base
, hspec
, QuickCheck
default-language: Haskell2010
and when I call stack ide targets I don't see these 2 targets. So, stack build api-tests and stack build e2e-tests don't work too.
How can I create 2 targets' project for stack? I tried also package.yaml but result is the same. Stack version is 1.9.1. I have folders tree like:
api/
...
e2e/
...
where are Main.hs files with content like:
module Main (main) where
main :: IO ()
main = print "Hello"
Also I tried option -main-is Main but without success.
Error looks like:
Error: While constructing the build plan, the following exceptions were encountered:
Unknown package: api-tests
AFAIK, stack build always builds all your targets. But if you want to be run just one executable, you'll need the full name including the -exe. So, stack exec api-tests-exe and stack exec e2e-tests-exe.
But what you really want to do is make these test targets: https://www.haskell.org/cabal/users-guide/developing-packages.html#test-suites
Problem was in stack.yaml file, I had to add '.' folder to "packages:" section.

how to use a specific branch of llvm-general with stack

In one of my projects I want to use llvm-general and llvm-general-pure but I want to use the llvm-3.9 branch which works with llvm 3.9, the latest version of these libraries on hackage are for llvm 3.5.
My project is a stack project, this is what I have in stack.yaml :
resolver: nightly-2017-05-01
packages:
- '.'
- location:
git: https://github.com/bscarlet/llvm-general.git
commit: 61fd03639063283e7dc617698265cc883baf0eec
subdirs:
- llvm-general
- llvm-general-pure
extra-dep: true
All other options are left to default.
This is my project.cabal :
name: compiler-final
version: 0.1.0.0
category: Compiler
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
library
hs-source-dirs: src
exposed-modules: Lexer,Parser,ParserTestData,CodeGen
other-modules: Prelude,StateTUtil
ghc-options: -Wall -dcore-lint -fhpc -XNoImplicitPrelude -fobject-code
build-depends: base-noprelude >= 4.7 && < 5 , megaparsec < 6 , transformers < 1, unordered-containers < 1 , hashable < 2
,classy-prelude , either < 5 , mono-traversable < 2 , logfloat < 0.14 , text
default-language: Haskell2010
default-extensions: OverloadedStrings
executable compiler-final-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -XNoImplicitPrelude -with-rtsopts=-N -fobject-code
build-depends: base
, compiler-final
default-language: Haskell2010
default-extensions: OverloadedStrings
test-suite compiler-final-test
type: exitcode-stdio-1.0
hs-source-dirs: test
other-modules: LexerSpec , ParserSpec
main-is: Spec.hs
build-depends: base
, compiler-final, megaparsec < 6 , hspec < 3,hspec-megaparsec >= 0.3,unordered-containers < 1
,hashable,transformers < 1,text,bytestring , mtl, text
ghc-options: -threaded -rtsopts -with-rtsopts=-N -fhpc -Wall -XNoImplicitPrelude -fobject-code
default-language: Haskell2010
default-extensions: OverloadedStrings
Benchmark compiler-final-bench
type: exitcode-stdio-1.0
hs-source-dirs: bench
main-is: Bench.hs
other-modules: ParserBench
build-depends: base,compiler-final,megaparsec < 6 ,unordered-containers < 1,QuickCheck<3
,hashable
ghc-options: -rtsopts -auto-all -caf-all -fforce-recomp -fobject-code
default-language: Haskell2010
Unfortunately in CodeGen.hs this simple import statement doesn't compile : import LLVM.General.AST, it says it didn't find the module.
Now I have llvm-general branch 3.9 installed globally through cabal install and I can access it with ghci -package(not stack ghci) and the above module exists.
I tried adding llvm-general and llvm-general-pure to my dependencies list with version 3.9.0.0 but stack seems to try to install version 3.5 because it reports errors about mismatched versions.
So how to achieve what I want ?
Your .cabal does not list llvm-general and llvm-general-pure as dependencies, hence why LLVM.General.AST is not being found.
Moreover, your stack.yaml is pointing to master, so stack will only see version 3.5. stack doesn't know anything about version 3.9 if it's not in the stack.yaml file. Either:
change the commit to ec1ad5bd2112e7f64dbb43441b5e2075cf6ad8e;
or, if you have the branch cloned locally, you can replace the whole location field corresponding to the repository with
- location: 'path/to/llvm-general'
extra-dep: true
- location: 'path/to/llvm-general-pure'
extra-dep: true

How to use HUnit in Stack

I have a stackproject stapro with a file app/Main.hs
module Main where
import Lib
main = putStrLn "This is main"
foo::Int ->Int
foo = (+1)
and a file test/Spec.hs
module Spec where
import Test.HUnit
import Main (foo)
main :: IO ()
main = putStrLn "Test suite not yet implemented"
testFoo :: Test
testFoo = TestCase $ assertEqual "Should return 2" 2 (foo 1)
When I try to execute the tests however
$ stack test
While constructing the BuildPlan the following exceptions were encountered:
-- While attempting to add dependency,
Could not find package Main in known packages
-- Failure when adding dependencies:
Main: needed (-any), stack configuration has no specified version
needed for package stapro-0.1.0.0
My .cabal file is
name: stapro
version: 0.1.0.0
...
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
library
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
default-language: Haskell2010
executable stapro-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, stapro
default-language: Haskell2010
test-suite stapro-test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: base
, stapro
, HUnit
, Main
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010
...
It looks like you're trying to depend on the executable (Main in build-depends of the test-suite section), so that you can test it in your test suite. That doesn't work, in fact you can't really test your executable at all.
Remove Main from the build-depends. Move all the code you want to test into your library.

Profiling library via executable in cabal

Silly question. I have a cabal file with a library and an executable that I would like to use to profile the library, but I can't manage to see cost centers from my library (although I see some from other modules like GHC.IO.Encoding).
Here's a simplified version of my cabal file
flag dev
default: False
manual: True
library
exposed-modules: Foo
ghc-options: -Wall
ghc-prof-options: -fprof-auto
build-depends: base
executable dev-example
if !flag(dev)
buildable: False
ghc-options: -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -ddump-core-stats -ddump-inlinings
ghc-options: -O2 -rtsopts
ghc-prof-options: -fprof-auto
hs-source-dirs: dev-example, ./
main-is: Main.hs
build-depends: base
Where I've been doing
$ cabal configure -fdev -w /usr/local/bin/ghc-7.6.3 --enable-library-profiling --enable-executable-profiling
$ cabal run dev-example -- +RTS -h -p
Ugh, the issue was simply that my library code was being inlined (or at least marked INLINABLE).

Resources