如何使用不同键类型的IntMap?

Zhe*_*hen 5 haskell types

我在一个使用两个IntMaps的文档中有一条记录:

data Doc = Doc { kernels :: IntMap Kernel, nodes :: IntMap Node }
Run Code Online (Sandbox Code Playgroud)

但是我发现来自两个IntMaps的键具有不同的含义,并且我无法在两种不同类型中分离,并且在混合内核类型和节点类型时不会出错.我想要有从内核映射和节点映射检查密钥的函数,并且不允许混淆.例如:

someFunction :: Doc -> KernelKey -> NodeKey -> a
someFunction doc k1 k2 = .....
Run Code Online (Sandbox Code Playgroud)

而不是当前:

someFunction :: Doc -> Int -> Int -> a
someFunction doc k1 k2 = .... -- warning check twice k1 and k2
Run Code Online (Sandbox Code Playgroud)

它可以吗?或者我将IntMap改为Map.

谢谢

ham*_*mar 11

您可以使用newtype包装Int来区分它们的含义.

newtype KernelKey = KernelKey Int
newtype NodeKey = NodeKey Int

someFunction :: Doc -> KernelKey -> NodeKey -> a
someFunction doc (KernelKey k1) (NodeKey k2) = ...
Run Code Online (Sandbox Code Playgroud)

这样,你仍然可以在IntMap内部使用,但是暴露一个更加类型安全的接口,特别是如果你还控制KernelKeyNodeKey值的创建方式,即你不导出它们的构造函数,这样用户只能将它们作为其他函数的返回值.

请注意,newtype包装器在运行时会消失,因此这种额外的包装和展开不会以任何方式影响性能.