Найти в Дзене

Монады в Scala - просто о сложном

Изучая Scala Вам рано или поздно придётся столкнуться с довольно специфичной темой, без которой дальше продвигаться не представляется возможным. Монады - что это за блюдо, и с чем их едят? Как мне кажется, проще всего их можно описать одним словом - контейнер. Контейнер, несущий в себе значение переменной, массива, объекта, да всего чего угодно, но как обычно, всегда есть одно НО... Честно говоря, "но" не одно, а целых три - это основоположные законы монады, эдакий "контракт", который они обязуются выполнять, т.к. монаду может запилить кто угодно - надо чтобы они были в чём-то похожи, верно? Начнём с того, что у каждой монады в скале есть метод создания монады и метод flatMap, рассмотрим его: flatMap() сам по себе, как метод, появился из двух различных методов - map() и flatten(). map() - это метод применения какой-либо функции к содержимому, а flatten() - метод "устранения" излишней вложенности. В общем, если у вас есть двойной массив [][] - то после flatten() останется один, содержащ

Изучая Scala Вам рано или поздно придётся столкнуться с довольно специфичной темой, без которой дальше продвигаться не представляется возможным. Монады - что это за блюдо, и с чем их едят?

Как мне кажется, проще всего их можно описать одним словом - контейнер. Контейнер, несущий в себе значение переменной, массива, объекта, да всего чего угодно, но как обычно, всегда есть одно НО...

Честно говоря, "но" не одно, а целых три - это основоположные законы монады, эдакий "контракт", который они обязуются выполнять, т.к. монаду может запилить кто угодно - надо чтобы они были в чём-то похожи, верно? Начнём с того, что у каждой монады в скале есть метод создания монады и метод flatMap, рассмотрим его:

flatMap() сам по себе, как метод, появился из двух различных методов - map() и flatten(). map() - это метод применения какой-либо функции к содержимому, а flatten() - метод "устранения" излишней вложенности. В общем, если у вас есть двойной массив [][] - то после flatten() останется один, содержащий все элементы, не очень точно, зато понятен смысл, надеюсь. Не трудно догадаться, что flatMap() - это устранение вложенности вместе с применением функции, изи? Гоним дальше.

Left unit law

И так, первый закон таков : monad.apply(x) flatMap f == f(x). Тут довольно просто : если внутри монады находится позитивное значение, то применение flatmap к монаде и функции f будет равно обычному применению функции к тому же значению.

Right unit law

Второй закон гласит: monad(x) flatMap monad.apply == monad - значит это лишь то, что при объявлении создания монады внутри метода flatMap не создаёт излишней вложенности, мы получим монаду, а не монаду в монаде.

Associativity law

Тут уже поинтересней, но без замудрений его можно описать как обязательство последовательного выполнения применяемых функций, звучит непонятно, наверно, но станет ясно когда будем разбираться с for-comprehension.

Понимание этой части приходит не сразу, но, разобравшись получше, использование монад избавляет от лишней головной боли, улучшает читаемость кода и повышает аппетит.

Напишите, о чём Вы хотели бы узнать больше - это может стать темой следующих постов!