Применение функции, которая возвращает тип Monad в список, используя функцию map - PullRequest
1 голос
/ 01 марта 2020

Скажем, я хочу применить простую функцию (\x -> x+1) ко всем элементам в списке [1,2,3].

Я делаю map (\x -> x+1) [1,2,3] и получаю как ожидалось [2,3,4]. Тип возвращаемого значения - Num a => [a].

. Что теперь произойдет, если моя функция возвращает тип Monad и определена как \x -> do return x+1? Я хочу как-то применить эту функцию ко всем элементам в списке и получить обратно тип (Monad m, Num a) => m [a].

И значение будет таким же [2,3,4], только завернутым в монаду.

Я боролся с этим некоторое время без особого прогресса. Любая идея, как я могу сопоставить эту функцию с моим списком?

Ответы [ 2 ]

5 голосов
/ 01 марта 2020

Вы ищете mapM. Вы можете найти его с помощью Hoogle и просто набрав

Monad m => (a -> m b) -> [a] -> m [b]

Вы найдете его в первых нескольких результатах. Единственное отличие в сигнатуре типа состоит в том, что она обобщается на Traversable:

mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)

. С ее помощью вы можете делать такие вещи, как

> mapM (Just . (+) 1) [1,2,3]
> Just [2,3,4]

Или, чуть менее тривиально:

> mapM (\x -> if x < 5 then Just x else Nothing) [1..10]
> Nothing
2 голосов
/ 01 марта 2020

Существует версия map monadi c, называемая mapM:

mapM (\x -> return (x+1)) [1,2,3]
...