Haskell

[Haskell] Name clashes

2016-12-27  本文已影响10人  何幻

名字

一个模块名是一系列用点号分隔的标识符。这些标识符首字母都是大写,点号两边没有空格。
一个qualified name由模块名.unqualifed name构成。

例子

-- A.hs
module A where    -- 导出了A.f
  f = 1

-- B.hs
module B where    -- 导出了B.f
  f = 2

-- C.hs
module C(A.f) where    -- 导出了A.f
  import A    -- 导入了f, A.f
  import B    -- 导入了f, B.f
  f = 3

-- D.hs
module D(A.f, B.f) where    -- A.f与B.f的unqualifed name相同,但是引用的entity不同,报错
  import A    -- 导入了f, A.f
  import B    -- 导入了f, B.f
  f = 4

-- E.hs
module E(A.f,C.f) where    -- A.f与B.f的unqualifed name相同,引用的entity也相同,警告
  import A    -- 导入了f, A.f
  import C    -- 导入了f, C.f
  f = 5

-- F.hs
module F where    -- 导出了F.f
  import A as G    -- 导入了f, G.f
  import B as G    -- 导入了f, G.f
  f = 6

(1)模块C中,import Aimport B同时导入了f,但不会报错。
(2)模块C中,定义了自己的f不会报错,并且可以使用C.f来引用。
(3)在模块C中使用f的时候,会报错:Ambiguous occurrence ‘f’,因为f可能引用了模块A中的f,或模块B中的f,或模块C自己的f
(4)模块D使用(A.f, B.f),导出相同unqualifed name的不同entity,会报错:Conflicting exports for ‘f’
(5)模块E使用(A.f, C.f),导出相同unqualifed name的同一个entity,会警告:f’ is exported by ‘C.f’ and ‘A.f’
(6)模块F,将模块A中的f导入为G.f,将模块B中的f也导入为G.f不会报错,但是在使用G.f时会报错:Ambiguous occurrence ‘G.f’

总结

(1)导入时的名字冲突(不论是qualified name F.hs还是unqualified name C.hs),不会报错,但是使用这个有歧义的名字会报错。
(2)导出列表中的名字,去掉了模块名后得到unqualifed name,同名引用了不同的entity会报错(D.hs),同名引用了相同的entity会警告(E.hs)。
(3)模块中定义内部名字的时候,它是一个unqualifed name,但也会同时创建一个qualifed name(C.hs)。这个内部名字可能会与其他导入的unqualifed name冲突,但是不会报错,只会在引用这个unqualifed name的时候报错。

上一篇下一篇

猜你喜欢

热点阅读