好吧,所以我花了一整天的时间研究Haskell语言报告(2010),并发现了各种"有趣"的边缘案例。你认为应该是错误的东西,但这实际上是允许的。
特别是,考虑以下词汇语法参考摘录(第10.2节):
reservedid → case | class | data | default | deriving | do | else
| foreign | if | import | in | infix | infixl |
| infixr | instance | let | module | newtype | of
| then | type | where | _
您可能期望在该列表中看到qualified
…但它并不存在。(就这一点而言,as
或hiding
也不是。)
现在我在想…这是否报告中的意外疏忽?还是这是一个深思熟虑的设计决定?
看来GHC至少遵循了规范的字母,因为它将愉快地允许您定义一个名称实际上是qualified
的变量。奇怪,但却是真的。因此,这个名字似乎只是在一个上下文中的"特殊"。相比之下,您可以从不命名变量module
。只有在文件的开头,我们才能让这个词变得特别…但我们没有。
qualified
、as
和hiding
只作为关键字出现在特定的地方,因此可以用作变量名。
qualified
仅发生在import
之后as
仅出现在import qualified PACKAGE
之后hiding
仅出现在import [qualified] PACKAGE [as NAME]
之后
当你指出module
可能是这些特定于位置的关键词之一时,我明白你的意思了,但将任何东西命名为module
似乎都违背直觉。也许以前版本的Haskell允许在一个文件中包含多个模块?
qualified
和hiding
也可以这样说,但我经常使用as
,就像这样:
zip [] _ = []
zip _ [] = []
zip (a:as) (b:bs) = (a, b) : zip as bs
因此,考虑到这一点,我认为这确实是一个设计决定,我认为许多语言*都可以参与其中。
值得指出的是,deriving
可能是其中一个词,因为它总是跟在数据声明后面,foreign
也是如此,因为它只保留了FFI扩展名。
*尤其是javascript,它有一个庞大的列表,主要是毫无意义的保留字
首先,关键字"as"、"hiding"one_answers"qualified"不在Haskell的原始定义中。当添加它们时,出于向后兼容性的考虑,它们没有被做成保留字。添加保留字是破解代码的可靠方法。这是一个深思熟虑的决定。
其次,据我所知,Haskell并没有禁止每个文件有多个模块。该规范根本不涉及文件。(但我不知道有什么实现允许它。)