Using GHCi, import submodule that needs to import another submodule?

Hi, I am trying to figure out how to import one submodule from a hierarchical module in GHCi. For example, at the end of Chapter 6 of LYAHFGG (page 106-107), there's an example of a hierarchical module. Or at the bottom of this page, http://learnyouahaskell.com/modules If I recreate that module on my system and try to import, this is the output: [~/Geometry]$ ls Cube.hs Cuboid.hs Sphere.hs [~/Geometry]$ ghci GHCi, version 7.6.3: 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 Geometry.Sphere <no location info>: Could not find module `Geometry.Sphere' It is not a module in the current program, or in any known package. Prelude> :set -iGeometry Prelude> import Geometry.Sphere <no location info>: Could not find module `Geometry.Sphere' It is not a module in the current program, or in any known package. Prelude> :load Sphere [1 of 1] Compiling Geometry.Sphere ( Sphere.hs, interpreted ) Ok, modules loaded: Geometry.Sphere. *Geometry.Sphere> :load Cube Cube.hs:6:18: Could not find module `Geometry.Cuboid' Use -v to see a list of the files searched for. Failed, modules loaded: none. Prelude> :load Cuboid [1 of 1] Compiling Geometry.Cuboid ( Cuboid.hs, interpreted ) Ok, modules loaded: Geometry.Cuboid. *Geometry.Cuboid> :load Cube Cube.hs:6:18: Could not find module `Geometry.Cuboid' Use -v to see a list of the files searched for. Failed, modules loaded: none. Prelude> So I can't just "import Geometry.Sphere", and I tried setting -i, but that doesn't seem to help. Instead I have to ":load Sphere". Fine, but then when I try to ":load Cube", it fails because of the line in Cube.hs that imports Geometry.Cuboid. Even if I load Geometry.Cuboid first and then try to load Geometry.Cube, it still fails. So, in GHCi, how do I successfully import a submodule that needs to import some other submodule in the module? Thanks, James

Hi James, On Wed, Mar 05, 2014 at 12:07:33PM -0600, James Toll wrote:
So, in GHCi, how do I successfully import a submodule that needs to import some other submodule in the module?
[~/Geometry]$ cd .. [~]$ ghci
import Geometry.Sphere
Greetings, Daniel

On Mar 5, 2014, at 12:17 PM, Daniel Trstenjak wrote:
Hi James,
On Wed, Mar 05, 2014 at 12:07:33PM -0600, James Toll wrote:
So, in GHCi, how do I successfully import a submodule that needs to import some other submodule in the module?
[~/Geometry]$ cd .. [~]$ ghci
import Geometry.Sphere
Hi Daniel, Thank you for your suggestion. It appears that your suggestion partially works. Picking up from where I left off previously: Prelude> :q Leaving GHCi. [~/Geometry]$ cd .. [~/]$ ls Geometry/ clang-xcode5-wrapper.hs test.hs [~/]$ ghci GHCi, version 7.6.3: 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 Geometry.Sphere <no location info>: Could not find module `Geometry.Sphere' It is not a module in the current program, or in any known package. Prelude> :load Sphere <command line>: Could not find module `Sphere' Use -v to see a list of the files searched for. Failed, modules loaded: none. Prelude> :load Geometry.Sphere [1 of 1] Compiling Geometry.Sphere ( Geometry/Sphere.hs, interpreted ) Ok, modules loaded: Geometry.Sphere. *Geometry.Sphere> :load Geometry.Cube [1 of 2] Compiling Geometry.Cuboid ( Geometry/Cuboid.hs, interpreted ) [2 of 2] Compiling Geometry.Cube ( Geometry/Cube.hs, interpreted ) Ok, modules loaded: Geometry.Cube, Geometry.Cuboid. *Geometry.Cube> So import still does not work. But by trying “:load" from the parent directory, I was able to load Sphere, Cube and Cuboid. The problem is that it appears that only one is available at a time (i.e. loading Cube displaces Sphere). What’s more there is no way to do qualified imports. Regards, James

On Wed, Mar 05, 2014 at 12:39:01PM -0600, James Toll wrote:
Prelude> :load Geometry.Sphere [1 of 1] Compiling Geometry.Sphere ( Geometry/Sphere.hs, interpreted ) Ok, modules loaded: Geometry.Sphere. *Geometry.Sphere> :load Geometry.Cube [1 of 2] Compiling Geometry.Cuboid ( Geometry/Cuboid.hs, interpreted ) [2 of 2] Compiling Geometry.Cube ( Geometry/Cube.hs, interpreted ) Ok, modules loaded: Geometry.Cube, Geometry.Cuboid. *Geometry.Cube>
Use :add instead of :load for Geometry.Cube. :load loads the specified module but forgets anything that was previously loaded. :add loads a module without forgetting previously loaded things. The differeces between :load, :add, and :module/import are somewhat subtle and certainly confusing. You may find http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/interactive-evaluatio... helpful. -Brent

On Mar 5, 2014, at 12:47 PM, Brent Yorgey wrote:
On Wed, Mar 05, 2014 at 12:39:01PM -0600, James Toll wrote:
Prelude> :load Geometry.Sphere [1 of 1] Compiling Geometry.Sphere ( Geometry/Sphere.hs, interpreted ) Ok, modules loaded: Geometry.Sphere. *Geometry.Sphere> :load Geometry.Cube [1 of 2] Compiling Geometry.Cuboid ( Geometry/Cuboid.hs, interpreted ) [2 of 2] Compiling Geometry.Cube ( Geometry/Cube.hs, interpreted ) Ok, modules loaded: Geometry.Cube, Geometry.Cuboid. *Geometry.Cube>
Use :add instead of :load for Geometry.Cube. :load loads the specified module but forgets anything that was previously loaded. :add loads a module without forgetting previously loaded things.
The differeces between :load, :add, and :module/import are somewhat subtle and certainly confusing. You may find
http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/interactive-evaluatio...
Thank you for the suggestion. I will read up on scope and try using add. But what I would really prefer is to be able to import individual submodules in GHCi using standard import syntax from the GHCi command line: Prelude> import qualified Geometry.Sphere as Sphere Is that not possible? LYAHFFG seems to imply that it is, and Daniel’s response to this question seems to also suggest that it’s possible. Then I can control how the functions in the submodule are referenced. Thanks again, James

Hi James,
So import still does not work. But by trying “:load" from the parent directory, I was able to load Sphere, Cube and Cuboid. The problem is that it appears that only one is available at a time (i.e. loading Cube displaces Sphere). What’s more there is no way to do qualified imports.
Sorry about this one. 'import' depends on the available/installed ghc packages, the given module name 'Geometry.Sphere' is looked up in these packages. Calling 'ghc-pkg list' will give you a list of all packages. If you don't have created and installed a package for your geometry files, then ghci will not know them. So calling ':load/:add' is the right thing here. Greetings, Daniel

On Mar 5, 2014, at 1:18 PM, Daniel Trstenjak wrote:
Hi James,
So import still does not work. But by trying “:load" from the parent directory, I was able to load Sphere, Cube and Cuboid. The problem is that it appears that only one is available at a time (i.e. loading Cube displaces Sphere). What’s more there is no way to do qualified imports.
Sorry about this one. 'import' depends on the available/installed ghc packages, the given module name 'Geometry.Sphere' is looked up in these packages.
Calling 'ghc-pkg list' will give you a list of all packages.
If you don't have created and installed a package for your geometry files, then ghci will not know them.
So calling ':load/:add' is the right thing here.
Daniel et al., Thank you for the clarification. No worries. I appreciate you taking the time to respond to my question. One observation I could make as a beginner is that I wish the documentation made a better distinction between packages and modules. I suppose the ambiguity from my standpoint (please correct me if I’m wrong) is that all packages are, or include, modules, but not all modules are packages. As such, import would only be used for installed packages and not for my own modules. But the documentation for import routinely makes reference to modules, leading myself to incorrectly believe that I could import my own local modules using import. I’ve been reading through the page regarding scope that Brent referenced and feel as though it has clarified a few things, but also raised many more questions. Unfortunately it doesn’t make a clear distinction between packages and modules either. From http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/interactive-evaluatio... 2.4.5.1. :module and :load I’d love to get a clear definition of “loaded" vs "in scope". Does import only bring a module into scope, not load it? Then would installed packages be considered loaded but not in scope? But they don’t show up with :show modules. Would using import then place them in scope? My personal modules would be neither loaded, nor in scope? Using :load loads them and also places them in scope? Using :modules -m would remove a module from scope but it would still be loaded? Lots and lots of questions. If anyone has any links to documentation that would clear up some of these questions, I’d appreciate it. Anyway, it appears that using import is not possible for my modules, only for installed packages, so using :load and :add are the correct solution. Thanks again for the help, James

Hi James,
One observation I could make as a beginner is that I wish the documentation made a better distinction between packages and modules.
Unfortunately it's even a bit more complex. First of all there're the cabal packages which contain your haskell source files which define the modules. These cabal packages are build and installed by cabal and result into ghc packages, which are some kind of binary blob (I don't know the details) that contains all your modules in a compiled form, and these packages are readable by ghc/ghci. So 'import' refers to the modules of the ghc packages and ':load' refers to the modules in the source files.
2.4.5.1. :module and :load I’d love to get a clear definition of “loaded" vs "in scope".
':load' is pretty much the same as loading a package and importing a module from it, so ':load' does both at once. Everything that's imported is in scope.
Does import only bring a module into scope, not load it?
You've to load something before you can bring it with import into scope.
Then would installed packages be considered loaded but not in scope?
I think that ghci only loads and imports the packages defining the Prelude module at startup. All other packages are loaded lazily if you're importing a module of them.
Using :load loads them and also places them in scope?
Yes.
Using :modules -m would remove a module from scope but it would still be loaded?
I think so for ghc package modules, but I'm not sure for modules loaded with ':load', they might get unloaded again, but even if not, I don't think that you could get them back in scope by using 'import'. Greetings, Daniel

On Mar 6, 2014, at 4:06 AM, Daniel Trstenjak wrote:
Hi James,
One observation I could make as a beginner is that I wish the documentation made a better distinction between packages and modules.
Unfortunately it's even a bit more complex.
Daniel, Thanks for answering some of my many questions. I really appreciate your taking the time. I clearly still have a lot to learn on the subject but I appreciate the help. Thanks, James

If you want a source file to have a module Geometry.Cuboid, it should be in
a directory named Geometry and the file will have the name of Cuboid.hs.
In order to load that you have to start ghci in the directory that contains
the Geometry directory, not in the one that contains the source file.
So cd .., ghci Geometry/Cuboid.hs
On Wed, Mar 5, 2014 at 1:07 PM, James Toll
Hi,
I am trying to figure out how to import one submodule from a hierarchical module in GHCi. For example, at the end of Chapter 6 of LYAHFGG (page 106-107), there's an example of a hierarchical module. Or at the bottom of this page, http://learnyouahaskell.com/modules
If I recreate that module on my system and try to import, this is the output:
[~/Geometry]$ ls Cube.hs Cuboid.hs Sphere.hs [~/Geometry]$ ghci GHCi, version 7.6.3: 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 Geometry.Sphere
<no location info>: Could not find module `Geometry.Sphere' It is not a module in the current program, or in any known package. Prelude> :set -iGeometry Prelude> import Geometry.Sphere
<no location info>: Could not find module `Geometry.Sphere' It is not a module in the current program, or in any known package. Prelude> :load Sphere [1 of 1] Compiling Geometry.Sphere ( Sphere.hs, interpreted ) Ok, modules loaded: Geometry.Sphere. *Geometry.Sphere> :load Cube
Cube.hs:6:18: Could not find module `Geometry.Cuboid' Use -v to see a list of the files searched for. Failed, modules loaded: none. Prelude> :load Cuboid [1 of 1] Compiling Geometry.Cuboid ( Cuboid.hs, interpreted ) Ok, modules loaded: Geometry.Cuboid. *Geometry.Cuboid> :load Cube
Cube.hs:6:18: Could not find module `Geometry.Cuboid' Use -v to see a list of the files searched for. Failed, modules loaded: none. Prelude>
So I can't just "import Geometry.Sphere", and I tried setting -i, but that doesn't seem to help. Instead I have to ":load Sphere". Fine, but then when I try to ":load Cube", it fails because of the line in Cube.hs that imports Geometry.Cuboid. Even if I load Geometry.Cuboid first and then try to load Geometry.Cube, it still fails.
So, in GHCi, how do I successfully import a submodule that needs to import some other submodule in the module?
Thanks,
James
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (4)
-
Brent Yorgey
-
Daniel Trstenjak
-
David McBride
-
James Toll