Haskell 中有通用的 Hashable 类型类吗? (又名“派生(可哈希)”)

发布于 2024-11-08 18:19:28 字数 997 浏览 5 评论 0原文

有没有人编写了一个通用函数,以便可以为自定义数据类型自动生成哈希函数(使用派生机制)?有几次,我编写了以下类型的样板,

data LeafExpr = Var Name | Star deriving (Eq, Show)
instance Hashable LeafExpr where
    hash (Var name) = 476743 * hash name
    hash Star = 152857

这可以自动生成:基本思想是,每当添加数据时,都乘以素数,例如列表,

hash (x:xs) = hash x + 193847 * hash xs

本质上,我想写的是

data LeafExpr = ... deriving (Hashable)

编辑 1

感谢大家所有非常有帮助的回复。当我有时间时,我会尝试添加一个通用方法作为练习。现在(也许 sclv 指的是什么呢?),我意识到我可以编写稍微更好的代码,

instance Hashable LeafExpr where
    hash (Var name) = hash ("Leaf-Var", name)
    hash Star = hash "Leaf-Star"

使用 ghc编辑 2

乘以随机素数比编辑 1 中的元组效果好得多。与 Data.HashTable 的冲突从 95%(非常糟糕)上升到 36%。代码在这里: [ http://pastebin.com/WD0Xp0T1 ] [ http://pastebin.com/Nd6cBy6G ]。

Has anyone written a generic function so that hash functions can be generated automatically for custom data types (using the deriving mechanism)? A few times, I've written the following kind of boilerplate,

data LeafExpr = Var Name | Star deriving (Eq, Show)
instance Hashable LeafExpr where
    hash (Var name) = 476743 * hash name
    hash Star = 152857

This could be generated automatically: the basic idea is that whenever adding data, you multiply by a prime, for example with lists,

hash (x:xs) = hash x + 193847 * hash xs

Essentially, what I'd like to write is

data LeafExpr = ... deriving (Hashable)

Edit 1

Thanks for all of the very helpful responses, everyone. I'll try to add a generic method as an exercise when I have time. For now (perhaps what sclv was referring to?), I realized I could write the slightly better code,

instance Hashable LeafExpr where
    hash (Var name) = hash ("Leaf-Var", name)
    hash Star = hash "Leaf-Star"

Edit 2

Using ghc, multiplying by random primes works much better than tupling in edit 1. Conflicts with Data.HashTable went from something like 95% (very bad) to 36%. Code is here: [ http://pastebin.com/WD0Xp0T1 ] [ http://pastebin.com/Nd6cBy6G ].

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白云悠悠 2024-11-15 18:19:28

您需要多少速度?您可以使用使用模板 haskell 的包之一来生成 序列化代码将值转换为二进制,然后使用 hashable 对二进制数组进行哈希处理。

How much speed do you need? You could use one of the packages that use template haskell to generate serialization code to convert the value to binary and then hash the binary array with hashable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文