Творческое использование монад

Введение

Технический обзор - пропустить этот ответ .

Для распространенных случаев, когда происходит копирование - пропустить этот ответ .

Копирование elision - это оптимизация, выполняемая большинством компиляторов для предотвращения дополнительных (потенциально дорогостоящих) копий в определенных ситуациях. Он делает возвращение по значению или пропускной способностью практически осуществимым (применяются ограничения).

Это единственная форма оптимизации, которая исключает (ha!) Правило as-if - копирование может применяться даже если копирование / перемещение объекта имеет побочные эффекты.

Следующий пример, взятый из Wikipedia :

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C();
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

В зависимости от компилятора & amp; все допустимые значения:

Hello World! Была сделана копия. Была сделана копия.


Hello World! Копия была сделана.


Hello World!

Это также означает, что можно создавать меньше объектов, t полагаться на определенное количество вызываемых деструкторов. Вы не должны иметь критической логики внутри copy / move-constructors или destructors, так как вы не можете полагаться на их вызываемые.

Если вызов конструктора копирования или перемещения отменяется, этот конструктор должен все же существуют и должны быть доступны. Это гарантирует, что копирование не позволяет копировать объекты, которые обычно не могут быть скопированы, например. потому что у них есть частный или удаленный конструктор copy / move.

C ++ 17: Начиная с C ++ 17, Copy Elision гарантируется, когда объект возвращается напрямую:

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C(); //Definitely performs copy elision
}
C g() {
    C c;
    return c; //Maybe performs copy elision
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f(); //Copy constructor isn't called
}

51
задан Mauricio Scheffer 10 September 2014 в 07:35
поделиться

7 ответов

Phil Wadler написал многие работы на монадах , но тот для чтения сначала является большой забавой и будет доступен для любого программиста; это звонило сущность функционального программирования . Бумага включает исходный код и демонстрационные использования.

мой любимый А монада вероятности ; если можно найти Парк Sungwoo диссертация, он имеет много интересных примеров кода от робототехники.

30
ответ дан Norman Ramsey 7 November 2019 в 10:06
поделиться

Существует также LogicT (отслеживающий в обратном порядке преобразователь монады со справедливыми операциями и сокращающий).

Это имеет хорошее значение к Алгоритмам поиска AI из-за его конструкций для справедливой дизъюнкции, например, легко включая вычисления, которые успешно выполняются, бесконечное число времен, которые будут объединены (, чередовал ).

Это - использование, описан в ICFP '05 бумаги Отслеживание в обратном порядке, Чередование и Завершение Преобразователей Монады

16
ответ дан Herrmann 7 November 2019 в 10:06
поделиться

можно найти интересные и усовершенствованные монады в блоге Окружением Бесконечности . Я могу отметить Монада Векторного пространства , и ее использование для рациональные путаницы описание. К сожалению, я не думаю, что понимаю это достаточно хорошо для объяснения его здесь.

13
ответ дан haggai_e 7 November 2019 в 10:06
поделиться

Одна из моих любимых монад поисковая монада Martin Escardo . Это может быть найдено на hackage в infinite-search пакет .

Это - монада "поисковых функций" для ряда элементов типа a, а именно, (a -> Bool) -> Maybe a (нахождение элемента в наборе, соответствующем данному предикату).

10
ответ дан fizruk 7 November 2019 в 10:06
поделиться

Одно интересное использование монады находится в парсинге. Парсек является стандартным примером.

8
ответ дан mattiast 7 November 2019 в 10:06
поделиться

Читайте ряд статей о монадах раньше моделировал вероятность и вероятностные процессы здесь: http://www.randomhacks.net/articles/2007/03/03/smart-classification-with-haskell (переходят по ссылкам к предыдущим/следующим частям)

8
ответ дан ADEpt 7 November 2019 в 10:06
поделиться

Harpy , пакет для генерации машинного кода x86 во время выполнения, использует монаду генерации кода . Из описания:

Это комбинированная монада «читатель-состояние-исключение», которая обрабатывает все детали обработки буферов кода, выдачи двоичных данных, перемещения и т. Д.

Все функции генерации кода в модуле Harpy.X86CodeGen находятся в этом монадой и использовать ее средства сообщения об ошибках, а также внутреннее состояние, поддерживаемое монадой.

Пользователь библиотеки может передавать пользовательскую среду и пользовательское состояние через монаду. Это состояние не зависит от внутреннего состояния и может использоваться библиотеками генерации кода более высокого уровня для поддержания своего собственного состояния во время операций генерации кода.

Я нашел это особенно интересным примером, поскольку считаю, что этот шаблон не является редкостью: I ' d сам изобрел нечто очень похожее для генерации набора внутренних сообщений для моего приложения на основе сообщений, полученных из потока данных (фондовой) биржи. Оказывается, это чрезвычайно удобный способ заставить фреймворк отслеживать различные «глобальные» вещи, при этом составляя простые операции, которые сами по себе не сохраняют состояние.

Я сделал еще один шаг вперед в его идее наличия состояния пользователя ( которое я называю «подсостоянием»), которое также может быть передано через монаду: у меня есть механизм для отключения и восстановления состояния во время выполнения монады:

-- | Given a generator that uses different substate type, convert it
-- to a generator that runs with our substate type. As well as the
-- other-substate-type generator, the caller must provide an initial
-- substate for that generator and a function taking the final substate
-- of the generator and producing a new substate of our type. This
-- preserves all other (non-substate) parts of the master state touched
-- by the generator.
--
mgConvertSubstate :: MsgGen msg st' a -> st' -> (st' -> st) -> MsgGen msg st a

Он используется для подгрупп комбинаторов, у которых было собственное состояние, необходимое для короткий период. Они работают только со своим состоянием, ничего не зная о состоянии вызвавшего его генератора (что помогает сделать вещи более модульными),

8
ответ дан 7 November 2019 в 10:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: