【问题标题】:Why am I able to use my value constructor even though I don't export it?为什么我可以使用我的值构造函数,即使我不导出它?
【发布时间】:2015-01-23 18:04:56
【问题描述】:

为了练习,我在一个名为“队列”的模块中实现了一个队列数据类型。我的数据类型也称为“队列”,它唯一的值构造函数也是如此:

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,而不是Queue(..)Queue(Queue),所以我不希望模块导出我的数据类型的值构造函数。这正是我想要的,出于封装目的:用户不应该直接使用值构造函数;只有emptyQueueenq和我界面中的其他功能。

但是(对于经验丰富的 Haskeller 来说,我的问题的解决方案可能很明显),如果我在 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]}

如上所述,这是不可取的。我做错了什么?

【问题讨论】:

标签: haskell module encapsulation ghci value-constructor


【解决方案1】:

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

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

:m -Queue
:m +Queue

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

:m *Queue

另见官方文档中的What's really in scope at the prompt?

【讨论】:

  • 啊,是的!谢谢;我没有意识到这一点。这不是 GHCi 第一次捉弄我了。请添加对 GHCi 默认忽略范围规则的文档的引用,我会接受您的回答。
  • 我们真的应该尝试为此问题选择一个规范问题。它出现了很多很多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 2015-05-28
相关资源
最近更新 更多