Reputation: 392
Say I have a queue implementation in a file and wanted to import it to work in a main file. I'm having trouble figuring out how to properly do so without getting a constructor error.
Say I have this in one file Queue1.hs
module Queue1 (Queue, mtq, ismt, addq, remq) where
data Queue a = Queue1 [a] deriving (Show)
-- multiple methods defined . . .
Then in my main file say I have:
import Queue1
And wanted to do this, which adds a list to the beginning of the Queue
:
addq :: [a] -> Queue a -> Queue a
addq xs q = undefined
How exactly would I create the function so that I can use the Queue
methods defined in another file?
I have created the following variations with no success:
adds xs (Queue q) = (xs:q)
error: Not in scope: data constructor ‘Queue’
|
13 | adds xs (Queue q) = (xs:q)
I also tried defining another Queue
in the file which didn't work:
data Queue a = Queue3 [a] deriving Show
adds :: [a] -> Queue a -> Queue as
adds xs (Queue3 q) = Queue3(xs:q)
error:
Ambiguous occurrence ‘Queue’
It could refer to
either ‘Queue1.Queue’,
imported from ‘Queue1’ at lab3.hs:4:1-13
(and originally defined at Queue1.hs:17:1-41)
or ‘Main.Queue’, defined at lab3.hs:9:1
Can anyone point to what I'm doing wrong?
Upvotes: 2
Views: 204
Reputation: 70407
Data constructors are not exported for a type by default. This allows us to write abstract types which can only be manipulated via a well-defined interface. A well-known example of this is Data.Map
, which is internally a funny tree-like structure with lots of internal invariants, but the constructor isn't exported because the devs don't want you poking around and making invalid maps.
However, in this case, you want to export Queue
, both the type and the constructor, as it looks like you want users to be able to construct and pattern match against your type. The syntax to export a specific constructor is
module Queue1 (Queue(Queue1), mtq, ismt, addq, remq) where
If you want to export all of the constructors (and record fields, if there are any), then you can use the shortcut wildcard syntax
module Queue1 (Queue(..), mtq, ismt, addq, remq) where
In this case, that's equivalent to the first example, but if you had several constructors, then ..
would export them all.
Upvotes: 4