Как извлечь условия определенного конструктора данных из списка в Haskell

Типичная проблема я вошел в Haskell, состоит в том, чтобы извлечь все условия в списке, принадлежащем определенному конструктору данных, и я задаюсь вопросом, существуют ли какие-либо лучшие пути, чем способ, которым я делаю ее в данный момент.

Скажем, Вы добрались

data Foo = Bar | Goo

, список

foos = [Bar, Goo, Bar, Bar, Goo]

и хотите извлечь все Goos от foos. В данный момент я обычно делаю что-то как

goos = [Goo | Goo <- foos]

и все хорошо. Проблема состоит в том когда Goo получил набор полей, и я вынужден записать что-то как

goos = [Goo a b c d e f | Goo a b c d e f <- foos]

который далек от идеала. Как Вы действительно обычно решаете эту проблему?

13
задан Don Stewart 19 April 2011 в 01:45
поделиться

2 ответа

Похоже, этот вопрос состоит из двух частей:

  1. Есть ли более простой способ выполнить сопоставление с образцом
  2. Можно ли здесь использовать списки?

Во-первых, там - лучший способ сопоставить поля, которые вам не нужны:

goos = [ x | x@(Goo {}) <- foos]

Во-вторых, использование списков - это идеальный способ написания подобных фильтров. Например, в базовой библиотеке catMaybes определяется как:

catMaybes :: [Maybe a] -> [a]
catMaybes ls = [x | Just x <- ls]

(из базовой библиотеки). Так что с этой идиомой все в порядке.

23
ответ дан 1 December 2019 в 20:56
поделиться

Вы можете использовать

[x | x@(Goo _ _ _ _ _ _) <- foos]

Вы также можете определить

isGoo :: Foo -> Bool
isGoo (Goo _ _ _ _ _ _) = True
isGoo _ = False

, а затем использовать фильтр

filter isGoo foos

или

[x | x <- foos, isGoo]
5
ответ дан 1 December 2019 в 20:56
поделиться
Другие вопросы по тегам:

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