NoBugs
NoBugs

Reputation: 9496

loading .hs script into interpreter

In Haskell ghci, I tried

Prelude> :load filename.hs
Ok, modules loaded: Main.

unfortunately I can't run any of the functions defined in the file. I compiled the file without any errors, but calling function gives an error, "Not in scope: (function name)". The strange thing is, awhile earlier I had no problem running this...

Upvotes: 2

Views: 1237

Answers (5)

apusateri
apusateri

Reputation: 58

Not sure if this will help, but I just had the same issue.

Turns out the virtual that I was running GHCI in was out of space, so when I saved my files they were empty.

Trying to load the file looked like it succeeded ( Whatever.hs, interpreted) - but I got the same error.

Upvotes: 0

hammar
hammar

Reputation: 139830

You have probably compiled the module before so that there are .o and .hi files lying around in the directory. When GHCi finds these, it will by default load the module in compiled mode which means that only the stuff exported from the module is in scope.

If you didn't include a module declaration, this will by default only be main, since the default module declaration is module Main (main) where. This is also where the Main name comes from.

You can tell that this is happening from the prompt. Normally, when loading a module it will look like this:

Prelude> :load Foo.hs
[1 of 1] Compiling Main             ( Foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> 

The asterisk before Main means that the module is open in interpreted mode, and that everything in it is in scope, including stuff imported from other modules. However, if I had just compiled Foo.hs and then tried to load it into GHCi, I would instead see something like this:

Prelude> :load Foo.hs
Ok, modules loaded: Main.
Prelude Main> 

You can force interpreted mode by prefixing the file name with an asterisk:

Prelude> :load *Foo.hs
[1 of 1] Compiling Main             ( Foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> 

Upvotes: 0

Daniel Fischer
Daniel Fischer

Reputation: 183873

The language standard states that if no module declaration is given, it is implicitly module Main (main) where. When Haskell source files are compiled and then loaded into ghci, only the exported entities of the module in question are in scope. In your case, without a module declaration, that is only the main function.

However, since that is quite inconvenient while developing, ghci can load interpreted modules with a wider scope, cf. the users' guide. Modules loaded in that form are indicated by an asterisk before the module name in the prompt, and for such modules, not only every top-level entity defined in the module is in scope, but also imported entities, everything in scope at the top-level of the module is also available at the ghci prompt when a module is loaded in that form.

That allows convenient testing of functions in development and is therefore a Good Thing™. On the other hand, as @ehird rightfully mentions, the difference in behaviour can be confusing and is therefore a bad thing.

On the whole, I think the advantages of ghci's wider scope for *Modules outweigh the inconsistency.

Upvotes: 1

ehird
ehird

Reputation: 40787

The problem is that your editor is compiling the code with something like

$ ghc foo.hs

Since your file doesn't have a module declaration, GHC assumes the module is called Main, since you didn't specify otherwise and, since it's compiling a full program, doesn't export any of the definitions other than main; that is, it acts as if you have a module declaration like:

module Main (main) where

Whereas GHCi defaults to:

module Main where

These module declarations specify the name of the module you're compiling, and which values are exported. With the first declaration, only main is exported from the module; with the second case, every top-level value is exported. Values that aren't exported can't be accessed from outside the module, which is why you get the "not in scope" errors in GHCi.

GHCi's inconsistent behaviour is presumably to make testing code easier; you don't have to have a module declaration to load a file and use its definitions. The solution is to put module Main where (or some other module name) at the top of your file, which explicitly exports everything. Personally, I think this behaviour is confusing, and the behaviour of GHC and GHCi should probably be changed to be consistent.

Upvotes: 3

Tikhon Jelvis
Tikhon Jelvis

Reputation: 68152

It's hard to guess exactly what the issue is. Did you change the line on top of the file from something like:

module Main where

to something like:

module Main (main) where

If you did, it would only export the main function.

Upvotes: 0

Related Questions