Типичная проблема я вошел в Haskell, состоит в том, чтобы извлечь все условия в списке, принадлежащем определенному конструктору данных, и я задаюсь вопросом, существуют ли какие-либо лучшие пути, чем способ, которым я делаю ее в данный момент.
Скажем, Вы добрались
data Foo = Bar | Goo
, список
foos = [Bar, Goo, Bar, Bar, Goo]
и хотите извлечь все Goo
s от foos
. В данный момент я обычно делаю что-то как
goos = [Goo | Goo <- foos]
и все хорошо. Проблема состоит в том когда Goo
получил набор полей, и я вынужден записать что-то как
goos = [Goo a b c d e f | Goo a b c d e f <- foos]
который далек от идеала. Как Вы действительно обычно решаете эту проблему?
Похоже, этот вопрос состоит из двух частей:
Во-первых, там - лучший способ сопоставить поля, которые вам не нужны:
goos = [ x | x@(Goo {}) <- foos]
Во-вторых, использование списков - это идеальный способ написания подобных фильтров. Например, в базовой библиотеке catMaybes определяется как:
catMaybes :: [Maybe a] -> [a]
catMaybes ls = [x | Just x <- ls]
(из базовой библиотеки). Так что с этой идиомой все в порядке.
Вы можете использовать
[x | x@(Goo _ _ _ _ _ _) <- foos]
Вы также можете определить
isGoo :: Foo -> Bool
isGoo (Goo _ _ _ _ _ _) = True
isGoo _ = False
, а затем использовать фильтр
filter isGoo foos
или
[x | x <- foos, isGoo]