Data.Foldable для неупорядоченных контейнеров

Я работаю над языком Haskell-meet-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].

Что называется эта идея? Если я ушел с базы, где я оставил базовый путь?

Ответ 1

Операция, выполняемая вашим сгибаемым оператором, не будет работать над моноидом, а скорее коммутативной полугруппой. Это дает вам op :: (CSemi a) => f a -> a -> a

В литературе, которую я видел, типичное имя для вашего оператора /typeclass будет просто CFold - коротким для коммутативной складки. (YAHT также использует cfold в качестве имени для спс-стиля, но я не думаю, что это обычно используется)