为什么我能够使用我的值构造函数,即使我不导出它?

jub*_*0bs 8 haskell encapsulation module ghci value-constructor

实际上,我正在一个名为"Queue"的模块中实现队列数据类型.我的数据类型也称为"队列",它是唯一的值构造函数:

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)...
Run Code Online (Sandbox Code Playgroud)

据我所知,因为我写的Queue,不是Queue(..)Queue(Queue)在导出语句中,我不希望模块导出我的数据类型的值构造函数.这正是我想要的,为了封装目的:用户不应该直接使用值构造函数; only emptyQueue,enq和我界面中的其他功能.

然而(并且我的问题的解决方案对于经验丰富的Haskellers来说可能是显而易见的),如果我在GHCi中加载我的模块,我可以直接使用值构造函数.

$ 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]}
Run Code Online (Sandbox Code Playgroud)

如上所述,这是不希望的.我究竟做错了什么?

Dan*_*ner 14

你没有做错任何事.只是为了方便起见,ghci忽略了它加载的模块的范围规则.

如果你想看看通常可用的东西,你可以

:m -Queue
:m +Queue
Run Code Online (Sandbox Code Playgroud)

您可以稍后返回"一切皆有可用"模式

:m *Queue
Run Code Online (Sandbox Code Playgroud)

另请参见提示符范围内的真实内容?在官方文档中.