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

2023-11-23

作为实践,我在名为“Queue”的模块中实现了队列数据类型。我的数据类型也称为“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)...

据我了解,因为我写了Queue, not Queue(..) or Queue(Queue)在导出语句中,我不希望模块导出我的数据类型的值构造函数。这正是我想要的,出于封装目的:用户不应该能够直接使用值构造函数;仅有的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]}

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


你没有做错什么。只是为了方便起见,ghci 忽略了它加载的模块的作用域规则。

如果您想查看通常可用的内容,您可以

:m -Queue
:m +Queue

您可以稍后返回到“一切可用”模式

:m *Queue

也可以看看提示符下真正的范围是什么?在官方文档中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐