Еще одна попытка объяснить монады, используя только списки Python и функцию map
. Я полностью согласен с тем, что это не полное объяснение, но я надеюсь, что оно дойдет до основных понятий.
Я получил это из видео funfunfunction на Monads и в главе «Learn You A Haskell» «Еще несколько монад» . Я очень рекомендую посмотреть видео с интересными функциями.
Очень просто, монады - это объекты, которые имеют функции map
и flatMap
(bind
в Haskell). Есть некоторые дополнительные обязательные свойства , но это основные.
flatMap
'выравнивает' выходные данные карты, для списков это просто объединяет значения списка, например.
concat([[1], [4], [9]]) = [1, 4, 9]
Итак, в Python мы можем очень просто реализовать Monad только с этими двумя функциями:
def flatMap(func, lst):
return concat(map(func, lst))
def concat(lst):
return sum(lst, [])
func
- любая функция, которая принимает значение и возвращает список, например,
lambda x: [x*x]
Объяснение
Для ясности я создал функцию concat
в Python с помощью простой функции , которая суммирует списки, т.е. [] + [1] + [4] + [9] = [1, 4, 9]
(у Haskell есть собственный метод concat
).
Я предполагаю, что вы знаете, что такое функция map
, например ::1010 *
>>> list(map(lambda x: [x*x], [1,2,3]))
[[1], [4], [9]]
Сглаживание является ключевым понятием монад, и для каждого объекта, который является монадой, это сглаживание позволяет получить значение, заключенное в монаде.
Теперь мы можем позвонить:
>>> flatMap(lambda x: [x*x], [1,2,3])
[1, 4, 9]
Эта лямбда принимает значение x и помещает его в список. Монада работает с любой функцией, которая переходит от значения к типу монады, поэтому список в этом случае.
Это ваша монада, определенная .
Я думаю, что вопрос о том, почему они полезны, был дан ответ на другие вопросы.
Больше объяснений
Другими примерами, не являющимися списками, являются обещания JavaScript, которые имеют метод then
, и потоки JavaScript, которые имеют метод flatMap
.
Таким образом, Promises и Streams используют немного другую функцию, которая выравнивает Stream или Promise и возвращает значение изнутри.
Монада списка Haskell имеет следующее определение:
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
т.е. Есть три функции return
(не путать с возвратом в большинстве других языков), >>=
(flatMap
) и fail
.
Надеюсь, вы увидите сходство между:
xs >>= f = concat (map f xs)
и
def flatMap(f, xs):
return concat(map(f, xs))