Отфильтруйте [Maybe a] и отбросьте значения Nothing

Со списком Maybe a как отфильтровать и взять только те элементы списка, которые не являются Nothing?

-- input
pas = [Just 3, Just 1, Just 5, Just 9, Nothing, Just 10, Nothing] :: [Maybe Int]

-- expected output
new_pas = [3, 1, 5, 9, 10]

Я пробовал разные способы использования map и смотрел на mapMaybe, но не могу найти правильную комбинацию.


person Jivan    schedule 20.10.2020    source источник
comment
map сам по себе не может фильтровать. concat . map (\case Nothing -> [] ; Just x -> [x]) будет. (конечно, ваш ответ на понимание списка показывает, что он лучше написан с помощью LC).   -  person Will Ness    schedule 27.10.2020


Ответы (3)


Помимо простого понимания списка, которое вы нашли, для этого уже есть библиотечная функция: catMaybes

И обратите внимание, что вы можете искать в Hoogle не только имена, но и сигнатуры типов, что действительно полезно во многих ситуациях. Здесь ввод [Maybe a] -> [a] дает вам сразу catMaybes. (Признание: я забыл название функции, но, зная, что она существует, только что нашел ее именно такой!)

person Robin Zigmond    schedule 20.10.2020

Набирая вопрос, я нашел ответ, и он на самом деле прост:

new_pas = [pa | Just pa <- pas]
-- [3, 1, 5, 9, 10]

Поместите это здесь, чтобы другие люди гуглили тот же вопрос.

person Jivan    schedule 20.10.2020

Ваш способ сопоставления с образцом в понимании списка довольно хорош. Тем не менее, мне также нравится, как Data.Maybe.mapMaybe вы упомянули (обратите внимание, что это всего одна строка в разделе Data.Maybe.catMaybe, о котором говорится в этом ответе от Robin Zigmond):

unwrapJusts :: [Maybe a] -> [a]
unwrapJusts = mapMaybe id

Ваш пример:

GHCi> unwrapJusts [Just 3, Just 1, Just 5, Just 9, Nothing, Just 10, Nothing]
[3,1,5,9,10]

Идея довольно проста: при обходе списка mapMaybe id отбрасывает все Nothing (которые являются id Nothing) и превращает Just x в x.

person Zhiltsoff Igor    schedule 20.10.2020