commercialhaskell / stack

The Haskell Tool Stack
http://haskellstack.org
BSD 3-Clause "New" or "Revised" License
3.99k stars 845 forks source link

`stack ghci` doesn't let me use modules from executables #347

Closed cdepillabout closed 9 years ago

cdepillabout commented 9 years ago

I have a simple project that creates an executable. The executable has four modules (Main, Api, Config, Models). Here is the project I am playing around with:

https://github.com/parsonsmatt/servant-persistent

When using cabal, I am able to use and play around with these four modules from the repl:

$ cabal sandbox init
...
$ cabal install
...
$ cabal repl
Package has never been configured. Configuring with default flags. If this
fails, please run configure manually.
Resolving dependencies...
Configuring servant-persistent-0.1.0.0...
Preprocessing executable 'perservant' for servant-persistent-0.1.0.0...
GHCi, version 7.10.1: http://www.haskell.org/ghc/  :? for help
[1 of 4] Compiling Config           ( src/Config.hs, interpreted )
[2 of 4] Compiling Models           ( src/Models.hs, interpreted )
[3 of 4] Compiling Api              ( src/Api.hs, interpreted )
[4 of 4] Compiling Main             ( src/Main.hs, interpreted )
Ok, modules loaded: Config, Main, Api, Models.
*Main Prelude > import Config
*Main Prelude Config > import Models
*Main Prelude Config Models > import Api
*Main Prelude Config Models Api > 

However, with stack, it looks like these modules don't get placed in the environment:

$ stack build
...
$ stack ghci
Configuring GHCi with the following packages: servant-persistent
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 Main

<no location info>:
    Could not find module ‘Main’
    It is not a module in the current program, or in any known package.
Prelude > import Api

<no location info>:
    Could not find module ‘Api’
    It is not a module in the current program, or in any known package.
Prelude > 

Is there any way to get this to work with stack?

chrisdone commented 9 years ago

This is because import only works on modules that have already been loaded. You can use :l Main.

stack ghci doesn't load your whole project on start-up. I thought that not naming it repl would avoid people assuming they behave the same, but it looks like that isn't going to work.

Anyway, I can make it load everything on start-up by default and add a flag like --no-load for people like me who don't want to load all 100 modules of a project just to look at one.

rvion commented 9 years ago

+1 for loading everything by default

cdepillabout commented 9 years ago

Great! I didn't realize specific modules could be loaded with :l Main.

cdepillabout commented 9 years ago

Also, I don't know if it is related, but is it possible to load modules that only exist in tests as well?

For example, with cabal I could run cabal repl test to have all the test libraries available in the repl. Is this possible with stack?

I asked a similar question on reddit.

chrisdone commented 9 years ago

Currently all libraries are available from all targets, so you should just be able to :l test/X.hs?

cdepillabout commented 9 years ago

Okay, thanks! That solves all my problems.

I'm okay with this being closed unless more people want the feature where everything is loaded by default.

I guess I'm neutral on the matter. It might be nice for people like me who expect to just be able to do something like import Main.

chrisdone commented 9 years ago

Let's keep it open, I think other people want the loading by default thing.

chrisdone commented 9 years ago

Should be resolved on master. Please retry.

Note: It will only load "modules". It won't load Main modules for the executable or bench marks or test suites, because they conflict. So for that you should load the filename manually with :load src/main/Main.hs or whatnot.

cdepillabout commented 9 years ago

@chrisdone: This isn't working for me for some reason.

I tried it with lens, but I am getting the following error:

$ stack ghci
Configuring GHCi with the following packages: lens
GHCi, version 7.10.1: http://www.haskell.org/ghc/  :? for help
<command line>: cannot satisfy -package criterion
    (use -v for more information)
$

Do you have any idea what could be going on?

Here's the steps I took to test it with the lens library:

# get lens-4.11
$ stack unpack lens-4.11
# create a suitable stack.yaml file
$ cat stack.yaml
flags: {}
packages:
- '.'
extra-deps:
    - bifunctors-5
    - semigroupoids-5.0.0.2
    - profunctors-5.1.1
    - free-4.12.1
resolver: nightly-2015-06-11
$ stack build
...
In-place registering lens-4.11...
lens-4.11: install
Installing library in
/home/illabout/temp/what/lens-4.11/.stack-work/install/x86_64-linux/nightly-2015-06-11/7.10.1/lib/x86_64-linux-ghc-7.10.1/lens_DA5uGsy5YTc4IwqrVVp2WP
Registering lens-4.11...
Completed all 7 actions.
$ stack ghci
Configuring GHCi with the following packages: lens
GHCi, version 7.10.1: http://www.haskell.org/ghc/  :? for help
<command line>: cannot satisfy -package criterion
    (use -v for more information)
$
cdepillabout commented 9 years ago

Oh yeah, my stack version looks like it should have your commits:

$ stack --version
Version 0.1.0.0, Git revision f724a32d5e3a727194eeab246695d7fd46f98374 (dirty)
$
cdepillabout commented 9 years ago

Also, unlike #394, I don't think I have anything in my ~/.ghc/ghci.conf that is causing this failure. Here is my ghci.conf:

-- Make the prompt a little more colorful.
:set prompt "\001\ESC[01;35m\002%s \001\ESC[01;34m\002> \001\ESC[m\002"
:set prompt2 "\001\ESC[01;35m\002%s \001\ESC[01;31m\002| \001\ESC[m\002"

-- OverloadedStrings is often useful.
:set -XOverloadedStrings

-- Scoped type variables is often useful so we can specify the types
-- of variables (for example, in lambda expressions).
:set -XScopedTypeVariables

-- Import Prelude.  Some projects don't import the Prelude by default, but
-- we are using types and functions from the Prelude in the following hoogle
-- function definition, so we need to make sure that Prelude is imported.
import Prelude

-- give us a `hoogle` function to if the hoogle binary is available.
:def hoogle \s -> return $ ":! hoogle --count=15 \"" ++ s ++ "\""

-- Show the types of evaluated expressions
:set +t

-- Enable multi-line expressions with :{ and :}
:set +m
chrisdone commented 9 years ago

Probably because lens requires stack in its benchmark target which I set to be enabled by default when resolving dependencies. Choices:

cdepillabout commented 9 years ago

I'm sorry, I don't have enough knowledge of cabal/stack/ghc to comment intelligently on which choice is the best.

As an end user, I would like stack ghci to work similarly to cabal repl. I would also like to be able to do something like :load test/testmain.hs to play with the tests from ghci. I'm not sure which of the three choices above would be best.

chrisdone commented 9 years ago

cabal repl refuses to run if all the dependencies aren't installed.

chrisdone commented 9 years ago

@snoyberg What do you think? I'm leaning towards stack ghci basically running stack build with benchmarks and tests enabled (in other words: ensure all dependencies are available for all targets being loaded), under the assumption that you'd only run GHCi if you were hacking on that project, so you'd probably be running tests and benchmarks anyway.

cdepillabout commented 9 years ago

Ah, I think I understand now.

Probably because lens requires stack in its benchmark target which I set to be enabled by default when resolving dependencies.

I think you mean that lens requires criterion in its benchmark target? And criterion is not installed by default when just doing stack build? So when ghci starts, it looks for ALL the libraries needed by ALL targets (including the benchmark targets which didn't get built by stack build), and fails to find criterion.

snoyberg commented 9 years ago

@chrisdone That sounds reasonable to me

chrisdone commented 9 years ago

@cdepillabout Right, I meant requires criterion.

CRogers commented 9 years ago

Please can we load up the project dependencies as part of stack ghci (or stack repl if we want two distinct things)? The only real reason I open ghci with stack is to play around with my modules in my stack project.

It would also be nice if we were able to specify cabal component, similar to cabal repl <component-name>, with the default of loading all of them when it's not specified.

chrisdone commented 9 years ago

Closing.

@CRogers Opened issue here #727.

chrisdone commented 9 years ago

Continuing installation of dependencies in #629 with PR https://github.com/commercialhaskell/stack/pull/726.