Вот скучная прямая реализация:
findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
findM _ [] = return Nothing
findM f (x:xs) = do
found <- f x
if found
then return $ Just x
else findM f xs
Обратите внимание, что это findM
не применяется f
ни к каким предметам после найденного.Таким образом, он семантически отличается от реализации filterM
, которую вы опубликовали.
Вы не можете написать это на основе find
, не выходя из своего пути.У вас уже есть чистый список, но предикат (a -> m Bool)
не соответствует (a -> Bool)
, необходимому для find
.Если вы используете mapM
, чтобы применить предикат к каждому элементу, все, что вы получите, это [Bool]
, который вам нужно будет сопоставить с исходным списком.