Сопоставление с образцом Haskell на пустом множестве

Я изменяю некоторый код Haskell от использования списков к наборам. Я понимаю все требуемое, я думаю, но я не уверен, как скопировать соответствие на наборах. Списки имеют этот хороший литеральный синтаксис, который кажется твердым эмулировать с конструктором Set. Например, у меня мог бы быть некоторый код как это:

foo [] = []
foo x = other_thing

Как я могу написать этот код, таким образом, он использует Наборы вместо списков?

18
задан C. A. McCann 25 July 2010 в 01:27
поделиться

2 ответа

Ну, не можете.

Набор - это абстрактный тип данных [0] , который намеренно скрывает свое внутреннее представление, в первую очередь для поддержания инвариантов структуры данных, которые не могут быть статически принудительно реализованы системой типов (в частности, стандартным библиотека Data.Set.Set - дерево двоичного поиска).

Потеря способности сопоставления с образцом в абстрактном типе данных является неприятным сопутствующим ущербом, ну да ладно. Возможны следующие варианты:

  • Используйте логические предикаты и защитные механизмы, например null , как в ответе тринитиса.
  • Преобразовать набор в список. В большинстве случаев это глупо, но если вы все равно хотите перебирать набор, это работает достаточно хорошо.
  • Включите GHC ViewPatterns расширение , которое обеспечивает синтаксический сахар для использования функций доступа там, где обычно происходит сопоставление с образцом.
  • Избегайте в первую очередь проверок подобного рода - если у вас есть Набор , относитесь к нему как к набору и работайте с ним в целом для сопоставления, фильтрации и т. д. Не всегда возможно, но может привести к более чистому коду с меньшим количеством явных условий / итераций.

Шаблоны просмотра позволят вам написать что-то вроде этого:

foo (setView -> EmptySet) = []
foo (setView -> NonEmpty set) = other_thing

... где setView - это функция, которую вы пишете.Здесь не очень много выигрыша, но может быть хорошо для более сложных псевдошаблонов

, чтобы избежать явных проверок, помимо хорошо известных операций над множествами, таких как union и пересечение , рассмотрите возможность использования функций filter , partition , map и fold в Data.Set .

[0]: См. этот документ (предупреждение: PDF) для определения термина в том виде, в каком я его использую.

33
ответ дан 30 November 2019 в 05:54
поделиться
import qualified Data.Set as Set

foo set
  | Set.null set = bar
  | otherwise = baz
32
ответ дан 30 November 2019 в 05:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: