How to split up a file into modules in Haskell?

Tag: haskell Author: xy300007 Date: 2009-10-23

I'm having an issue with the syntax for modules. Basically I'm trying to split my code into two seperate files, one for the object I'm creating (AST), and one for all of my functions.


    --main.hs
    data AST = Add (AST) (AST)|
               Sub  (AST) (AST)|
               Mult (AST) (AST)|
               Ident Char|
               Num Int
               deriving Show

    aSTLeft (Num	l	) = (Num l)
    aSTLeft (Ident	l	) = (Ident l)
    aSTLeft (Add  l	_	) = l
    aSTLeft (Sub  l	_	) = l
    aSTLeft (Mult l	_	) = l
    aSTRight    (Num	r	) = (Num r)
    aSTRight    (Ident	r	) = (Ident r)
    aSTRight    (Add  _ r	) = r
    aSTRight    (Sub  _ r	) = r
    aSTRight    (Mult _ r	) = r

    isNum (Num x) = True
    isNum (Ident x) = False
    isNum (Add  (x)(y)) = False
    isNum (Sub  (x)(y)) = False
    isNum (Mult (x)(y)) = False

    --a lot more functions here

This works fine, but when I try to split the AST datatype into a seperate file,


    --ASTADT.hs
    module ASTADT (AST,aSTLeft,aSTRight) where
    data AST =    Add (AST) (AST)|
                  Sub  (AST) (AST)|
                  Mult (AST) (AST)|
                  Ident Char|
                  Num Int
                  deriving Show

    aSTLeft     (Num	l	) = (Num l)
    aSTLeft     (Ident	l	) = (Ident l)
    aSTLeft     (Add  l	_	) = l
    aSTLeft     (Sub  l	_	) = l
    aSTLeft     (Mult l	_	) = l
    aSTRight        (Num	r	) = (Num r)
    aSTRight        (Ident	r	) = (Ident r)
    aSTRight        (Add  _ r	) = r
    aSTRight        (Sub  _ r	) = r
    aSTRight        (Mult _ r	) = r

and


    --main.hs
    import ASTADT
    isNum (Num x) = True
    isNum (Ident x) = False
    isNum (Add  (x)(y)) = False
    isNum (Sub  (x)(y)) = False
    isNum (Mult (x)(y)) = False
    --a lot more functions here

Loading main.hs I get error message


    Undefined data constructor "Num"

I'm pretty sure its just an issue with my module syntax, but I've been completely stuck for several hours now. I'm working with Hugs. Thanks

You used the word Object in context with Haskell!!! Prepare to burn!

Best Answer

Module ASTADT exports just the AST data type, but not its constructors. This is useful if you want to hide the implementation details of your data types from the modules users.

In your case you don't want that, so to export the constructors you can specify them in the module ... where line after the data type, like AST (Num, Ident). For exporting all the constructors of the data type you can use (..) instead of naming them all explicitly:

module ASTADT (AST (..), aSTLeft, aSTRight) where
...

Other Answer1

Your export declaration for the data constructors should look something like

module ASTADT (AST (Add, Sub, Mult, Ident, Num), aSTLeft, aSTRight) where