首页 > 解决方案 > 背包使用示例

问题描述

我正在查看backpackwiki上的参考资料, 试图了解在哪些情况下使用backpack将被认为比其他 Haskell 功能(如类型类和类型族)更合适。

特别是,在的作者的这篇博backpack文中,展示了一个为正则表达式实现简单匹配器的示例。但是据我了解,相同的模块可以使用类型族进行编码。

有没有任何例子可以简明地展示背包相对于更传统的 Haskell 功能的优势?如果我上面提到的例子很好,你知道为什么使用类型族的解决方案会低于标准吗?

标签: haskelltypeclasstype-familieshaskell-backpack

解决方案


背包的主要好处:

  1. 保证没有性能开销(使用类型类可能会有性能开销,因为它们在 Haskell 中是如何实现的)。这在处理字符串数据类型、解析器、容器等时非常重要。
  2. 与使用类型类或类型族相比,代码更简洁、更好。

我写了一篇关于 Backpack 的特殊用法的博客文章:为容器数据结构实现多态接口:

拥有这样的容器接口允许:

  1. 编写适用于任何容器(例如MapHashMapIntMap)的多态函数。
  2. 为容器的属性编写单个测试套件,并在每个包中使用它,而无需重复代码。
  3. 编写单个基准测试并与每个容器数据结构一起使用,而不会产生性能开销。

如果使代码更清洁的话。这是groupBy使用 Backpack 实现的函数的签名:

groupBy :: forall k f a . (Foldable f, Key k) => (a -> k) -> f a -> Map k (NonEmpty a)

很清楚,它只是一个普通的 Haskell。如果您使用类型类和类型族为容器实现接口(这是在 中完成的relude,此签名将如下所示:

groupBy
    :: forall f t a . (Foldable f, DynamicMap t, Val t ~ NonEmpty a, Monoid t)
    => (a -> Key t) -> f a -> t

更难阅读和理解。

最近还讨论了当您需要编译针对不同平台的 Haskell 代码(也称为条件编译)时,Backpack 可以帮助避免 CPP。


推荐阅读