我正在研究一种用于数据库操作的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]
函数的语言和库,因为它引入了两者之间的二分法:
显然,sortBy :: (a -> a -> Ordering) -> Set a -> [a]
和shuffle :: Set a -> Data.Random.RVar [a]
都是有用的,无可非议的,并且会被包含在内。事实上,sortBy
的常规类型更为sortBy :: (TheUnorderedFoldableClassIAmTryingToName f) => (a -> a -> Ordering) -> f a -> [a]
。
这个想法叫什么?如果我离开基地,我在哪里离开基地路径?
答案 0 :(得分:2)
由类似褶皱的算子执行的操作不会在幺半群上运算,而是在可交换的半群上运算。这会给你op :: (CSemi a) => f a -> a -> a
在我看过的文献中,运算符/类型类的典型名称只是CFold - 交换折叠的缩写。 (YAHT也使用cfold作为cps式折叠的名称,但我不认为这是常用的)