Data.Foldable用于无序容器

时间:2011-11-23 20:21:51

标签: haskell typeclass parametric-polymorphism

我正在研究一种用于数据库操作的Haskell-meets-SQL语言,以及一个常见的类型类库,在Hackage的任何地方都可以使用它。

由于数据库查询优化器的一个重要目标是消除不必要的排序,因此保留实际需要排序的静态表示非常重要。这让我们为折叠定义了类型类。

Haskell的Data.Foldable具有:(忽略与我正在制定的点无关的默认定义)

class Foldable t where
  -- | Combine the elements of a structure using a monoid.
  fold :: Monoid m => t m -> m

  -- | Map each element of the structure to a monoid,
  -- and combine the results.
  foldMap :: Monoid m => (a -> m) -> t a -> m

  -- | Right-associative fold of a structure.
  foldr :: (a -> b -> b) -> b -> t a -> b

  -- | Left-associative fold of a structure.
  foldl :: (a -> b -> a) -> a -> t b -> a

  -- | A variant of 'foldr' that has no base case,
  -- and thus may only be applied to non-empty structures.
  foldr1 :: (a -> a -> a) -> t a -> a

  -- | A variant of 'foldl' that has no base case,
  -- and thus may only be applied to non-empty structures.
  foldl1 :: (a -> a -> a) -> t a -> a

在我看来,这个类忽略了一个区别,对于实际来说,这个区别对大多数Haskell应用程序来说并不那么重要,但对数据库设置更感兴趣。也就是说:所有Data.Foldable个实例都有一个排序。

这个概念的概括名称是什么,适用于不对其元素强加排序的容器类型?

对于Haskell Data.Set,它运行正常,因为实现需要Ord个上下文。排序要求虽然是一个实现工件,但对于许多有用的类型,使用的排序可能没有任何域级含义。

对于集合,更常见的是fold :: Monoid m => t m -> m定义本身大多是正确的(foldMap也是如此)。我之所以这么说,主要是因为它的类型包括相关性定律(通过Monoid的定义)而不是必需的交换法。其他变种甚至不存在。

我不想介绍不需要它们的种类。我也不想引入无法跟踪的非确定性。我有兴趣构建一个没有toList :: Set a -> [a]函数的语言和库,因为它引入了两者之间的二分法:

  1. 允许人们观察有关如何实际存储集合/关系的实施细节
  2. 失去对非决定论的影响
  3. 显然,sortBy :: (a -> a -> Ordering) -> Set a -> [a]shuffle :: Set a -> Data.Random.RVar [a]都是有用的,无可非议的,并且会被包含在内。事实上,sortBy的常规类型更为sortBy :: (TheUnorderedFoldableClassIAmTryingToName f) => (a -> a -> Ordering) -> f a -> [a]

    这个想法叫什么?如果我离开基地,我在哪里离开基地路径?

1 个答案:

答案 0 :(得分:2)

由类似褶皱的算子执行的操作不会在幺半群上运算,而是在可交换的半群上运算。这会给你op :: (CSemi a) => f a -> a -> a

在我看过的文献中,运算符/类型类的典型名称只是CFold - 交换折叠的缩写。 (YAHT也使用cfold作为cps式折叠的名称,但我不认为这是常用的)