For practice, I'm implementing a queue data type in a module called "Queue". My data type is also called "Queue", as is its only value constructor:
module Queue (Queue, enq, emptyQueue) where
data Queue a = Queue {
inbox :: [a],
outbox :: [a]
} deriving (Eq, Show)
emptyQueue :: Queue a
emptyQueue = Queue [] []
enq :: a -> Queue a -> Queue a
enq x (Queue inb out) = Queue (x:inb) out
-- other function definitions (irrelevant here)...
As far as I understand, because I wrote Queue
, not Queue(..)
or Queue(Queue)
in the export statement, I don't expect the value constructor of my data type to be exported by the module. This is exactly what I want, for encapsulation purposes: users should not be able to use the value constructor directly; only emptyQueue
, enq
, and the other functions in my interface.
However (and the solution to my problem may be obvious to seasoned Haskellers), if I load my module in GHCi, I'm able to use the value constructor directly.
$ ghci Queue.hs
GHCi, version 7.8.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Queue ( Queue.hs, interpreted )
Ok, modules loaded: Queue.
λ> Queue [1] [2]
Queue {inbox = [1], outbox = [2]}
As stated above, this is undesirable. What am I doing wrong?