Почему mconcat требует список, а не складной? - PullRequest
7 голосов
/ 09 февраля 2020

Рассматривая определение Monoid, я заметил, что mconcat имеет следующее определение ( источник ):

mconcat :: Monoid a => [a] -> a
mconcat = foldr mappend mempty

Почему подпись ограничивает это значение [a], а не более обобщенным c Foldable, как это?

mconcat' :: (Foldable t, Monoid a) => t a -> a
mconcat' = foldr mappend mempty

Это по историческим причинам? Или эта более общая реализация c усложнит для определенных типов c предоставление ее оптимизированной версии, как, например, для [], который использует понимание списка ( source )?

1 Ответ

8 голосов
/ 09 февраля 2020

Хотя я не знаю фактического обсуждения такого предложения, вот несколько возможных причин:

  • Обобщенная функция уже существует как fold из Foldable.

  • На самом деле, mconcat может быть полезным для реализации fold @[_], что может быть более эффективным, чем обычное значение по умолчанию для некоторых моноидов. (Я взял эту идею из GH C, выпуск № 17123 .)

  • Изменение сигнатур метода класса приводит к оттоку, поскольку экземпляры везде должны быть соответствующим образом скорректированы, и поэтому, как правило, это делается только тогда, когда есть насущная необходимость. (Кстати, сам Monoid был , хотя тщательно спланированный процесс был переработан для добавления Semigroup в качестве суперкласса, который может поддерживать или не поддерживать мою точку зрения.)

  • Специализированный тип mconcat имеет смысл, отражая то, как тип списка является кодировкой свободного моноида в Haskell. (Другим интересным фактом является то, что можно реализовать как mempty, так и mappend в терминах mconcat.)

...