`

СПЕЦИАЛЬНЫЕ
ПАРТНЕРЫ
ПРОЕКТА

Архив номеров

Как изменилось финансирование ИТ-направления в вашей организации?

Best CIO

Определение наиболее профессиональных ИТ-управленцев, лидеров и экспертов в своих отраслях

Человек года

Кто внес наибольший вклад в развитие украинского ИТ-рынка.

Продукт года

Награды «Продукт года» еженедельника «Компьютерное обозрение» за наиболее выдающиеся ИТ-товары

 

Андрей Зубинский

Опять про модные монады

+22
голоса

Без вступлений и отступлений.
Последний раз ныряю.

Монады - это всего лишь способ композиции функций.

Предположим, у нас есть функции, "входы-выходы" которых совпадают по типам аргументов и возвращаемых значений.

Например, три какие-то функции - F1, F2 и F3.

И мы с помощью некоторой операции композиции функций формируем из них новую функцию, возвращающую результат последовательного применения функций (пусть странный символ "==" обозначает "эквивалентно"):

Fn(x) == F1(  F2(  F3( x )))

Тут всё прозрачно, понятно и тривиально. Если, конечно, совпадают следующие типы:

  • x и аргумента F3
  • возвращаемого функцией F3 значения и аргумента F2
  • возвращаемого функцией F2 значения и аргумента F1
  • возвращаемого функцией F1 значения и возвращаемого Fn значения

А если эти типы не совпадают, что тогда ?

Очевидно, нужен некий дополнительный код, даже не приводящий типы, а именно обеспечивающий работоспособность всей конструкции в целом.

Почему в этом случае нельзя говорить о приведении типов достаточно очевидно - размерности наличествующих и требуемых типов могут не совпадать.

Например, функция F3 может принимать скалярное значение с плавающей точкой (float), а возвращать вектор из целых чисел.
А F2, например, способна обрабатывать только одно целое число.

Естественно, способ "соединить входы-выходы" этих двух функций есть.

И достаточно очевидный (псевдокод, более императивный, чем функциональный):

foreach i in F3( x ) F2( i )

То есть, "к каждому элементу возвращённого F3 вектора применить функцию F2".

Само собой, результатом такой композиции F3 и F2 будет уже не скаляр, а вектор.

Аналогично, если и F1 способна принимать только одно целое число, приём можно "продлить" и на неё:

foreach j in (foreach i in F3( x) F2( i )) F1( j )

Всё очевидно, но программист возмущённо кричит "многабукав" и "ниасилил" и требует чтобы было как-нибудь как можно проще и универсальней.

Например, просто так:

Fn(x) = compouse F1 F2 F3

Естественно, ничего идеального не бывает, и далеко не все отличающиеся параметрами и возвращаемыми значениями функции можно "связывать" в подобные композиции.
А только функции со вполне определёнными сигнатурами (аргументами, их порядком и типами, а также типом возвращаемого значения).

Пригодная к "монадированию" (ох и термины, ох и термины) функция обязана:

  • принимать скалярное значение какого-либо базового типа;
  • возвращать некоторый "контейнер", наполненный объектами какого-либо базового типа, такой "контейнер" условно назовём monadic-объектом.

В предыдущем примере базовым типом был тип скалярного объекта x - float, а monadic-объектом - возвращаемый функцией F3 вектор, "наполненный" целыми числами.

Для того, чтобы иметь возможность удобно применять пригодные к монадировнию функции в композициях, стало быть, надо всего лишь научиться изящно применять такие функции не к принимаемым ими базовым типам, а к monadic-объектам.

Изящно - без "лишнего" кодирования.

Для этого конструкция монад предусматривает функцию связывания, которая принимает в качестве параметров monadic-объект и монадируемую функцию, и внутри себя уже делает ту самую очевидную вещь, которую выше делал псевдокод foreach ...

Эту самую функцию "связывания" часто обозначают с использованием слова "bind", потому как она именно обеспечивает принципиальную возможность связывания "выходов" и "входов"  монадируемых функций.

Выглядит она как-то так примерно (в разных языках - по-разному, но суть не меняется совершенно):

monadic_bind( monadic_object, monadic_function)

и внутри делает примерно это самое:

foreach i in monadic_object monadic_function( i )

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

А теперь унифицируем конструкцию.
В том смысле, что исключим вообще непосредственную передачу даже параметра базового типа монадируемой функции, и потребуем всегда использовать для вызова монадируемых функций только monadic_bind.
Ну вот хочется нам так, чтобы всё было как в армии - пусть безобразно, зато однообразно.
Для этого, очевидно, нужен преобразователь объектов базовых типов в monadic-объекты, потому как monadic_bind никаких таких базовых типов принимать не умеет - не положено ей.
Этот преобразователь - ещё одна важная деталь монады.
И тоже, что характерно, функция, принимающая объект базового типа и возвращающая monadic-объект, контейнер, на дне которого валяется этот самый один несчастный объектик.
Назовём эту функцию, например, monadic_result.

Итого.

Монада - это комбинация из:

  • сигнатуры множества пригодных к монадированию функций, одной сигнатуры, что характерно, то есть точно определённого типа принимаемого функцией объекта базового типа в качестве параметра и monadic-объекта возвращаемого значения;
  • функции monadic_result, превращающей объект базового типа в monadic-объект (содержащий один этот же самый объект базового типа);
  • функции monadic_bind, позволяющей применять любую функцию заданной сигнатуры (монадируемую функцию) к любому monadic-объекту.

Всё.

Теперь можно очень просто строить любые композиции из любых функций, имеющих указанную сигнатуру.

Собственно, вот и вся суть монад, будь они неладны.

Вот и вся тайна.

+22
голоса

Напечатать Отправить другу

Читайте также

Прямая транслитерация может сыграть злую шутку.
По-русски монады -- это кое-что другое

Вот словарь Ушакова:
1. У древних математиков - единица.
2. У древних философов, напр. пифагорейцев, принцип, лежащий в основе бытия (филос.). ? В идеалистической философии Лейбница - одна из непротяженных, неделимых духовных единиц, как бы одушевленных атомов, из к-рых состоит мироздание (филос.).
3. Низший организм, переходный от растений к простейшим животным

Энциклопедия:
МОНАДА (от греч. monas - род. п. monados - единица, единое), понятие, обозначающее в различных философских учениях основополагающие элементы бытия: число в пифагореизме; единое в неоплатонизме; единое начало бытия в пантеизме Дж. Бруно; психически активная субстанция в монадологии Г. В. Лейбница, воспринимающая и отражающая др. монаду и весь мир ("Монада -
зеркало Вселенной").

http://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BD%D0%B0%D0%B4%D0%B0_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)

но что по сути претензий нет, это хорошо

 
 
IDC
Реклама

  •  Home  •  Рынок  •  ИТ-директор  •  CloudComputing  •  Hard  •  Soft  •  Сети  •  Безопасность  •  Наука  •  IoT