我正在开发一个引用unordered-containers-0.2.8.0:Data.HashMap.Base.HashMap
的项目。
包含该类型值的模块未说明导入部分的来源,我无法导入Data.HashMap.Base
。
然而,:bro
wsing表明该类型至少在某些情况下是抽象的。
> :bro Data.HashMap.Lazy
[...]
unordered-containers-0.2.8.0:Data.HashMap.Base.toList ::
unordered-containers-0.2.8.0:Data.HashMap.Base.HashMap k v
-> [(k, v)]
这是否意味着我可以从Lazy
或Strict
变体导入函数?
答案 0 :(得分:4)
是的,在unordered-containers
包中,您的目的是导入Data.HashMap.Lazy
或Data.HashMap.Strict
。两种变体都有严格的密钥(评估为WHNF),并且值是否也评估为WHNF也不同。
在unordered-containers
的源包中,有一个隐藏模块Data.HashMap.Base
,其中包含lazy和strict变体共享的代码。因为这个模块是隐藏的(从技术上讲,因为它列在包的Cabal文件中other-modules
节而不是exposed-modules
节),所以它不是直接导入的,而是仅通过一个间接导入其他两个模块。
特别是对于toList
,公开的模块Data.HashMap.Lazy
和Data.HashMap.Strict
都使用(即重新导出)隐藏模块中定义的toList
的相同定义{ {1}},这就是你在GHCI浏览中看到这个的原因。
如果您导入GHCI中的一个模块,那么您应该能够检查Data.HashMap.Base
及其组件类型:
toList
事实上,您会发现相同的> import Data.HashMap.Strict
> :t toList
toList :: HashMap k v -> [(k, v)]
> :i HashMap
type role HashMap nominal representational
data HashMap k v
= unordered-containers-0.2.7.2:Data.HashMap.Base.Empty
...
定义用于严格和惰性变体,因此它不是您所考虑的意义上的“抽象”类型:两个实现都使用相同的底层具体的数据结构,以及在该数据结构上运行的函数如何使用它。
顺便提一下,HashMap
和Data.Map.Strict
普通地图也是如此。 “严格”映射可以与惰性操作一起使用,反之亦然,因为“严格”和“惰性”映射是相同的对象。引用Data.Map.Lazy
的文档:
此模块的API在键中是严格的,但在值中是懒惰的。如果需要value-strict映射,请改用Data.Map.Strict。 Map类型本身在lazy和strict模块之间共享,这意味着可以将相同的Map值传递给两个模块中的函数(尽管很少需要)。