views:

95

answers:

2

I'm writing my first big project in Haskell and I'd like to split it across multiple files. So far, I have written two modules, Parse and Eval. I'd like to have a Main module that just includes these two modules and specifies the main function. I have the files Main.hs, Parse.hs, and Eval.hs and import them in Main, but this happens:

Prelude> :load "~/code/haskell/lisp/Main.hs"
[1 of 3] Compiling Eval             ( Eval.hs, interpreted )
[2 of 3] Compiling Parse            ( Parse.hs, interpreted )
[3 of 3] Compiling Main             ( ~/code/haskell/lisp/Main.hs, interpreted )
Ok, modules loaded: Main, Parse, Eval.
*Main> parse parseExpr "" "#b101"

<interactive>:1:0: Not in scope: `parse'

The parse function comes from Parsec library, which is imported in Parse.hs. What's wrong?

+3  A: 

From the Haskell report:

A module implementation may only export an entity that it declares, or that it imports from some other module. If the export list is omitted, all values, types and classes defined in the module are exported, but not those that are imported.

You either need to give an explicit export list that includes parse in Parse.hs, or import parse again in your Main.hs.

Travis Brown
A: 

You can also do this:

module Parse (parse) where
    import qualified Text.ParserCombinators.Parsec as P

    parse = P.parse

But really, this is useless. You'll certainly be wanting to build something more domain-specific on top of Parsec before you export it from one of your modules.

Michael Melanson