Haskell 为什么Data.Unique中的值在公开之前需要散列?
Haskell 为什么Data.Unique中的值在公开之前需要散列?,haskell,unique,ghc,base,Haskell,Unique,Ghc,Base,Data.Unique.hashUnique用于从Unique值获取几乎唯一的Int: hashUnique :: Unique -> Int #if defined(__GLASGOW_HASKELL__) hashUnique (Unique i) = I# (hashInteger i) #else hashUnique (Unique u) = fromInteger (u `mod` (toInteger (maxBound :: Int) + 1)) #endif 为什么Da
Data.Unique.hashUnique
用于从Unique
值获取几乎唯一的Int
:
hashUnique :: Unique -> Int
#if defined(__GLASGOW_HASKELL__)
hashUnique (Unique i) = I# (hashInteger i)
#else
hashUnique (Unique u) = fromInteger (u `mod` (toInteger (maxBound :: Int) + 1))
#endif
为什么Data.Unique
不提供像getUnique
这样的函数来获得真正唯一的值
getUnique :: Unique -> Integer
getUnique (Unique i) = i
这是图书馆发展中的疏忽吗?我们能把这样一个函数添加到数据中吗?在许多情况下,需要真正唯一的值。
数据。唯一的
值不是真正唯一的。如果您检查源代码,您将看到受保护的构造函数只是用一个计数器递增一个TVar
,每个唯一值都有下一个计数器值。所以你会得到一个Unique 1
然后是Unique 2
等等,但你可能已经知道了
由于整数是按递增顺序排列的,Integer
的散列仅仅是其存储在Int
中的整数值,因此您永远不会得到小于Int
限制的散列冲突(在64位机器上,Int
可以有18446744073709551615个不同的值)。所以,你基本上永远不会得到散列冲突
Unique
值保证在程序会话中是唯一的。仅此而已。它不能保证可打印或跨宇宙重复使用。如果需要可打印的通用唯一值,则应使用。为什么需要获取Int
或整数
。为什么不直接使用Unique
(真正的Unique)呢?因为我最终需要打印它。我知道Unique的语义及其用途。我的问题无论如何都是正确的。为什么库不必限制我使用maxBound::Int
unique值呢?unique
s定义散列值的唯一原因是可以对它们进行散列,例如将它们用作HashMap
s中的键。为什么hashString
函数返回一个Int
而不是一个包含所有String
s字节的Integer
?因为这不是hashString
函数的目的;它应该散列字符串。对于Unique
s,没有uniqueToInteger
函数的原因是它在内部使用Integer
s是一个实现细节。库开发人员应该可以自由地切换到ByteString
s,或者在不破坏代码的情况下进行切换。在某些情况下,拥有无限数量的唯一值非常有用(例如,考虑一个长期运行的服务器进程)。Data.Unique
库有可能填补这个角色,但目前没有。我对将此功能添加到库中感兴趣,或者有充分的理由反对它。然后制作一个计数器
库,其目的是生成无限数量的唯一整数值。不管怎么说,它只有大约10行代码。这不是数据的目的。Unique
生成唯一的整数,只生成唯一的值。它不能干净地添加。正如我所说,这将剥夺图书馆作者的一项自由;他将无法再替换实现细节(例如,如果他想从Integer
切换到ByteString
)。如果您不想添加黑客库,那么可以随意使用项目内部的模块。