Re[38]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 08:15
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Вариантов решения ровно 2


_>Ээээ вариантов решения чего? ) Какой проблемы то? Ты так и не сказал почему приведённый мною там код не сработает для промисов. Или ты не понял его идею, что он автоматом работает для всего, в том числе и для них? )


А кто его научит лифтинг делать в промисы ? Функции над самими промисами мне совершенно незачем выполнять.
Re[36]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 08:17
Оценка: :)
Здравствуйте, alex_public, Вы писали:

_>Если ты про ту свою задачку анализатора логов, то я ещё раз говорю, что для неё скорее всего просто императивный код на регулярных выражениях проще будет. Реактивный естественно. Т.е. что-то вроде:

_>
_>    if(regex_match(s, what, "/*длинный шаблон фильтрующий js*/")) js+=what[1];
_>


Давай закончим, а то ты дошел до парсинга джаваскрипта регэекспами
Re[56]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 08:50
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Так покажи уже эту пульку, сделай на ней реактивный парсер, а то одни слова.


_>Я же не сказал, что подобная библиотека существует. Хотя написать её никаких принципиальных проблем нет. Просто определённый объём работы.


http://www.cs.jhu.edu/CIRL/publications/pdf/DaHaPeTR2010frp.pdf
http://www.inf.fu-berlin.de/lehre/SS13/Sem-Prog/material/RC.pdf

I>>Мгновенная скорость никого не интересует, вообще. Когда говорят просто скорость, имеют ввиду все что угодно но не мгновенную скорость. И эта скорость имеет значение только на некотором временном интервале.


_>Ужас какой. ))) Скорость — это первая производная. И точка, без всяких вариантов.


И такая скорость никому не интересна. Увеличь частоту опроса хотя бы в 10 раз и попробуй глазом различить изменение скорости.

I>>Правильно и это легко делается — меняется размер интервала.


_>Ну так если в твоей задачке надо выводить алерты по значению средней скорости на каком-то интервале, то прямо так и сказал бы. Это конечно же чуть сложнее, чем вариант с просто скоростью — не одна строчка кода, а целых две.


И это, заметь, мы еще не говорили про комбинирование эвентов, например
кидать алёрт если скорость в период А другого сигнала выше определенного значения

Итого — на любое изменение требований тебе надо работать руками-руками-руками, например
1 асинхрронщна
2 многопоточность
3 обработка временных интервалов
4 комбинирование сигналов

Вот после того, как ты покажешь такие вещи, можно будет говорить про реактивное программирование
Re[32]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 09:00
Оценка: -1
Здравствуйте, alex_public, Вы писали:

_>Собственно это нормальный вариант и эти функции по любому определяются и в Хаскеле и в том моём примере. Только вот как ты и сам сказал, тебе придётся писать по отдельной реализации liftM2 для каждого типа монады, что уже совсем не дело.


И снова тот же вопрос — какое отношение имеет C# к монадам ?

_>Кстати, Klapaucius говорил как раз о чём-то подобном, когда намекал что у C++ могут быть какие-то сложности с реализацией liftM2. Похоже что его знания императивных языков ограничиваются как раз такими как C# и Java. )))


Он просто погорячился. У тебя вагон кода на ровном месте. Ради одного лифтинга никто потеть не будет. Минимум что необходимо это библиотечка навроде Boost.Phoenix, только для монад.
Отсюда, внезапно, можно сделать вывод — библиотечка будет еще страшнее чем Boost.Phoenix.
Ты открой и посмотри, феникс этот и есть то, как выглядит функциональщина в C++

I>>Все очень просто — этот декларативный код есть не что иное, как дсл в который упрятаны все императивные кишки которые у тебя торчат направо и налево


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


А мне постоянно кажется, что ты хочешь обратное доказать.

>Только это никак не связано с реактивностью, декларативностью или монадами.


Конечно, всё можно написать императивно на ассемблере, следовательно все что свыше — лишнее.

_>Если же сравнивать именно такие вещи, то надо взять с одной стороны эту твою библиотеку, а с другой скажем реактивный вариант boost.spirit и сравнить какой объём кода получается у них...


_>Кстати, тебе наверное должны нравиться вот такие https://github.com/beark/ftl/blob/master/docs/Parsec-I.md штуки... А мне это всё как-то совсем не нравится.
Re[32]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 09:06
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Кстати, тебе наверное должны нравиться вот такие https://github.com/beark/ftl/blob/master/docs/Parsec-I.md штуки... А мне это всё как-то совсем не нравится.


Я свою написал, небольшую, на C# и JS и сейчас хочу выпилить нормальный реактивный парсинг, потому что авторы всяких RX, beacon увлеклись созданием всемогуторов, которые ни в один проект в своём уме всунуть нельзя и практическая ценность около нуля.
Re[39]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 07.01.14 10:38
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>А кто его научит лифтинг делать в промисы ? Функции над самими промисами мне совершенно незачем выполнять.


Так это всё в функциях apply. Они перегружены по типу второго аргумента. Для "голых" значений будет просто применение функции, для монад/функторов применение к внутреннему значению (вот промисы сюда попадают), для коллекций stl поэлементное применение и т.п.

Да, и главное в такое схеме, что функций apply всего несколько (по количеству используемых монад или чего там ещё), а функции f,g, h никто не размножает, хотя они теперь как бы могут применяться к чему угодно...
Re[37]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 07.01.14 10:41
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Давай закончим, а то ты дошел до парсинга джаваскрипта регэекспами


Ещё раз, это не парсинг js (в смысле построения AST и т.п.), а поиск нужного нам в строке (ну и что, что там js код?) по шаблону. Не надо путать эти вещи. Если для решения нашей задачки достаточно второго, то совершенно ни к чему тащить в проект полноценный парсер js.
Re[40]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 11:00
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>А кто его научит лифтинг делать в промисы ? Функции над самими промисами мне совершенно незачем выполнять.


_>Так это всё в функциях apply. Они перегружены по типу второго аргумента. Для "голых" значений будет просто применение функции, для монад/функторов применение к внутреннему значению (вот промисы сюда попадают), для коллекций stl поэлементное применение и т.п.


То есть, вариант 1, ты хочешь лифтинг всунуть унутрь. Чем это отличается от обычного лифтинга — не ясно
Re[38]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 11:04
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, Ikemefula, Вы писали:


I>>Давай закончим, а то ты дошел до парсинга джаваскрипта регэекспами


_>Ещё раз, это не парсинг js (в смысле построения AST и т.п.), а поиск нужного нам в строке (ну и что, что там js код?) по шаблону. Не надо путать эти вещи. Если для решения нашей задачки достаточно второго, то совершенно ни к чему тащить в проект полноценный парсер js.


объясни, как ты собираешься скипнуть вот такой код, буде он придет в логе

function name(arg /*, ... камент*/){
      ... // произвольный код, т.е. любой валиднй код на JS
}


Из него нужно взять только name и только тогда, если весь блок является кодом на JS

Покажи уже решение — я обещаю, не буду выдавать его за своё и Нобелевская премия достанется только тебе
Re[57]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 07.01.14 11:06
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>http://www.cs.jhu.edu/CIRL/publications/pdf/DaHaPeTR2010frp.pdf

I>http://www.inf.fu-berlin.de/lehre/SS13/Sem-Prog/material/RC.pdf

Даже если забыть, что это просто теория, а не реальные библиотеки, то это всё равно на базе монад и прочего. А я говорил как раз о парсере с заданием грамматики в стиле Спирита, только реактивном.

I>И такая скорость никому не интересна. Увеличь частоту опроса хотя бы в 10 раз и попробуй глазом различить изменение скорости.


Вообще то скорость нужна не только для вывода на панель человеку. )))

I>Итого — на любое изменение требований тебе надо работать руками-руками-руками, например

I>1 асинхрронщна
I>2 многопоточность
I>3 обработка временных интервалов
I>4 комбинирование сигналов

I>Вот после того, как ты покажешь такие вещи, можно будет говорить про реактивное программирование


А я разве где-то говорил, что я предлагаю для всех случаев использовать код в лоб? Вообще то я писал прямо противоположное. Что мы можем реализовать нашу функцию Analyze любым удобным способом (а не один единственным, как в Rxx). Для простых случаев императивным кодом в лоб, а для сложных можем взять любые подходящие библиотеки (конечные автоматы, БНФ-парсеры и что угодно ещё). Ты внимательнее читай то, что я пишу и не придумывай за меня мои слова.
Re[33]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 07.01.14 11:16
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Он просто погорячился. У тебя вагон кода на ровном месте. Ради одного лифтинга никто потеть не будет. Минимум что необходимо это библиотечка навроде Boost.Phoenix, только для монад.


Ммм, нет, в данном случае объём кода абсолютно равный Хаскелю. Разница только в количестве всяких скобочек и т.п.

I>Отсюда, внезапно, можно сделать вывод — библиотечка будет еще страшнее чем Boost.Phoenix.

I>Ты открой и посмотри, феникс этот и есть то, как выглядит функциональщина в C++

Да, внутри будет именно так. Но для пользователя библиотеки всё будет просто супер.

Кстати, а полезность Boost.Phoenix на мой взгляд сильно изменилась с выходом C++11...

I>А мне постоянно кажется, что ты хочешь обратное доказать.


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

А так я вообще то сам люблю взять готовую библиотечку какую-нибудь. ))) Только вот использование готовой библиотеки совершенно не означает, что она должна быть на базе монад.
Re[33]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 07.01.14 11:19
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Я свою написал, небольшую, на C# и JS и сейчас хочу выпилить нормальный реактивный парсинг, потому что авторы всяких RX, beacon увлеклись созданием всемогуторов, которые ни в один проект в своём уме всунуть нельзя и практическая ценность около нуля.


Ооо, одобряю подход твой. Правда боюсь, что обойтись без монад всё равно не захочешь. )))

Кстати, насчёт той моей ссылки: реализация монадных парсеров — это у них просто типа примера использования библиотечки. А так у них цель немного другая. Что-то типа "притащить Хаскель в C++". ))) На мой взгляд нафиг не нужно, но тебе может будет любопытно взглянуть http://libftl.org.
Re[41]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 07.01.14 11:33
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>То есть, вариант 1, ты хочешь лифтинг всунуть унутрь. Чем это отличается от обычного лифтинга — не ясно


Лифтинг работает только на монадах (правда там как плюс можно сделать одну функцию на все виды монад). А тут мы можем работать вообще с чем угодно, причём сразу (один код сложной функции на все случаи). И ещё если в качестве этого "что угодно" будут "голые" значения, то мы не получим никаких накладных расходов.
Re[39]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 07.01.14 11:37
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>объясни, как ты собираешься скипнуть вот такой код, буде он придет в логе


I>
I>function name(arg /*, ... камент*/){
I>      ... // произвольный код, т.е. любой валиднй код на JS
I>}
I>


I>Из него нужно взять только name и только тогда, если весь блок является кодом на JS


А там у нас может быть не только js код? ) С чего бы это? По условиям задачки я такого не помню. Насколько я помню у нас внутри "pir:" только js код. Ну и если только js, то думаю не надо говорить как вырезать из этого name? )))
Re[58]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 12:04
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Даже если забыть, что это просто теория, а не реальные библиотеки, то это всё равно на базе монад и прочего. А я говорил как раз о парсере с заданием грамматики в стиле Спирита, только реактивном.


С++ не умеет те операторы, которые нужны для БНФ или РБНФ.
то есть придется эмулировать все подряд, например следование придется пилить явно, скобки и прочую вешь так же придется эмулировать, т.е. пилить явно.
Вот смотри, твой спирит, я даже не знаю, не то смеяться, не то плакать.
namespace calculator_grammar
{
    using x3::uint_;
    using x3::char_;
 
    x3::rule<class expression, ast::program> const expression;
    x3::rule<class term, ast::program> const term;
    x3::rule<class factor, ast::operand> const factor;
 
    auto const expression_def =
        term
        >> *(   (char_('+') >> term)
            |   (char_('-') >> term)
            )
        ;
 
    auto const term_def =
        factor
        >> *(   (char_('*') >> factor)
            |   (char_('/') >> factor)
            )
        ;
 
    auto const factor_def =
            uint_
        |   '(' >> expression >> ')'
        |   (char_('-') >> factor)
        |   (char_('+') >> factor)
        ;
 
    auto const calculator = x3::grammar(
            expression = expression_def,
            term = term_def,
            factor = factor_def
        );
}
 
using calculator_grammar::calculator;



вот BNF:

expr = term | term '+' term | term '-' term
term = factor '*' factor | factor '/' factor
factor = number | '(' expr ')' | '-' factor | '+' factor
number = digit {digit}
digit = '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'


Итого — в спирите раз в 7-8 раз больше кода чем в бнф грамматике, при том что два правила сидят в самой либине — digit и uint, если их добавить, кода будет в 10 раз больше

А вот фокус — та же грамматика на комбинаторах
var term = empty(); 
var unary = empty();
var number = rep1(range('0..9'))
var expr = or(term, seq(term, or('-+'), term))
var term = term.overWrite(seq( factor, or('*/'), factor))
var factor = or(number, seq('(',expr,')'), unary)
var unary = unary.overWrite(seq(or('-+'), factor))


тут не всё, справа надо добавить .map(AST.ляляля), т.е. трансляцию в АСТ, количество кода не сильно изменится

Итого — спирит сосёт не нагибаясь.

I>>И такая скорость никому не интересна. Увеличь частоту опроса хотя бы в 10 раз и попробуй глазом различить изменение скорости.

_>Вообще то скорость нужна не только для вывода на панель человеку. )))

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

I>>Итого — на любое изменение требований тебе надо работать руками-руками-руками, например

I>>1 асинхрронщна
I>>2 многопоточность
I>>3 обработка временных интервалов
I>>4 комбинирование сигналов

I>>Вот после того, как ты покажешь такие вещи, можно будет говорить про реактивное программирование


_>А я разве где-то говорил, что я предлагаю для всех случаев использовать код в лоб? Вообще то я писал прямо противоположное.


Твои частные случаи неинтересны, это аргумент в духе "всё пишется на ассемблере -> ЯВУ не нужен"
Re[40]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 12:14
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Из него нужно взять только name и только тогда, если весь блок является кодом на JS


_>А там у нас может быть не только js код? ) С чего бы это? По условиям задачки я такого не помню. Насколько я помню у нас внутри "pir:" только js код. Ну и если только js, то думаю не надо говорить как вырезать из этого name? )))




js он паттерном идёт, как раз для того, что бы отделить от остального мусора

Очевидно, что в логе не только JS, там результаты функций, снимки состояния и тд и тд.
Re[42]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 12:16
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>То есть, вариант 1, ты хочешь лифтинг всунуть унутрь. Чем это отличается от обычного лифтинга — не ясно


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


Пудозреваю, тебе самое время смотреть boost.phoenix
Re[34]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 12:24
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Я свою написал, небольшую, на C# и JS и сейчас хочу выпилить нормальный реактивный парсинг, потому что авторы всяких RX, beacon увлеклись созданием всемогуторов, которые ни в один проект в своём уме всунуть нельзя и практическая ценность около нуля.


_>Ооо, одобряю подход твой. Правда боюсь, что обойтись без монад всё равно не захочешь. )))


Можно и без монад — получатся автоматы на коленке с конской вложенностью, простынями из свичей и все это будет размазано по десяткам эвентов.

_>Кстати, насчёт той моей ссылки: реализация монадных парсеров — это у них просто типа примера использования библиотечки. А так у них цель немного другая. Что-то типа "притащить Хаскель в C++". ))) На мой взгляд нафиг не нужно, но тебе может будет любопытно взглянуть http://libftl.org.


Эта хрень такая же страшная, как и boost.phoenix. Все такие возможности очень актуальны, ибо в С++ возможностей для интеграции около нуля. Именно по этой причине для интеграции берут более другой язык — JS, Python, Lua и тд вплоть до С# или Джавы, не гнушаясь даже vbs.
Re[34]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 07.01.14 12:27
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, Ikemefula, Вы писали:


I>>Он просто погорячился. У тебя вагон кода на ровном месте. Ради одного лифтинга никто потеть не будет. Минимум что необходимо это библиотечка навроде Boost.Phoenix, только для монад.


_>Ммм, нет, в данном случае объём кода абсолютно равный Хаскелю. Разница только в количестве всяких скобочек и т.п.


Я чет не заметил, в хаскеле одна прозрачная строчка а у тебя только первяс строчка, что из темплейтов, и уже втрое длиннее.

I>>Отсюда, внезапно, можно сделать вывод — библиотечка будет еще страшнее чем Boost.Phoenix.

I>>Ты открой и посмотри, феникс этот и есть то, как выглядит функциональщина в C++

_>Да, внутри будет именно так. Но для пользователя библиотеки всё будет просто супер.


Я в это не верю. За все время ни разу не видел либы, в которую не надо было бы лазить при разработке.
Re[33]: [trick] nested monad DO-sugar in C++
От: Evgeny.Panasyuk Россия  
Дата: 07.01.14 13:21
Оценка:
Здравствуйте, Ikemefula, Вы писали:

_>>Кстати, Klapaucius говорил как раз о чём-то подобном, когда намекал что у C++ могут быть какие-то сложности с реализацией liftM2. Похоже что его знания императивных языков ограничиваются как раз такими как C# и Java. )))

I>Он просто погорячился. У тебя вагон кода на ровном месте. Ради одного лифтинга никто потеть не будет. Минимум что необходимо это библиотечка навроде Boost.Phoenix, только для монад.
I>Отсюда, внезапно, можно сделать вывод — библиотечка будет еще страшнее чем Boost.Phoenix.
I>Ты открой и посмотри, феникс этот и есть то, как выглядит функциональщина в C++

Boost.Phoenix даёт:
  • лямбды — с приходом лямбд в C++11 менее актуально
  • полиморфные лямбды — с приходом полиморфных лямбд в C++14 менее актуально
  • короткую нотацию для лямбд, причём даже короче чем в C#: (_1 + _2)(11, 22) == 33

    А DO-сахар для монад реализуются ровно в сорок строк без всякого Phoenix'а:
    #include <boost/optional.hpp>
    
    #include <iostream>
    #include <utility>
    #include <cassert>
    
    using namespace std;
    using namespace boost;
    
    // Simple Monad:
    template<typename T>
    struct Simple
    {
        T data;
        template<typename F> friend auto operator>>=(Simple m, F f)
        {
            return f(m.data);
        }
    };
    
    // Maybe Monad:
    template<typename F, typename T>
    auto operator>>=(optional<T> m, F f)
    {
        return m ? f(m.get()) : m;
    }
    
    template<template<typename> class Monad>
    auto run()
    {
        return
            DO(Monad,
                (x, unit(1))
                (y, unit(2))
                (z, DO(Monad,
                    (x, unit(5))
                    (_, unit(x - 2))
                ))
                (_, unit(x + y + z))
            );
    }
    
    int main()
    {
        assert( run<Simple>().data == 6 );
        assert( run<optional>().get() == 6 );
        assert
        (
            not DO(optional,
                (x, unit(1))
                (y, unit(2))
                (z, DO(optional,
                    (x, make_optional(false, 5))
                    (_, unit(x - 2))
                ))
                (_, unit(x + y + z))
            )
        );
        cout << "DONE" << endl;
    }

      implemetation
    #include <boost/fusion/adapted/struct/adapt_struct.hpp>
    #include <boost/preprocessor/facilities/expand.hpp>
    #include <boost/preprocessor/arithmetic/dec.hpp>
    #include <boost/preprocessor/seq/for_each.hpp>
    #include <boost/preprocessor/seq/elem.hpp>
    #include <boost/preprocessor/seq/size.hpp>
    #include <boost/preprocessor/cat.hpp>
    
    template<template<typename> class Monad>
    struct MonadUnit
    {
        template<typename T> auto operator()(T x) const
        {
            return Monad<T>{x};
        }
    };
    
    #define SEQ_LAST(SEQ) BOOST_PP_SEQ_ELEM( BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(SEQ)), SEQ)
    
    #define STMT_TAIL(r, data, elem) };
    
    #define LAST_STMT(var, code) unit( var );
    
    #define STMT_HEAD_AUX(var, code) code >>= [=](auto var) { return
    #define STMT_HEAD(r, data, elem) STMT_HEAD_AUX elem
    
    #define DO_AUX(SEQ) \
        BOOST_PP_SEQ_FOR_EACH(STMT_HEAD, _, SEQ) \
        BOOST_PP_EXPAND(LAST_STMT SEQ_LAST(SEQ)) \
        BOOST_PP_SEQ_FOR_EACH(STMT_TAIL, _, SEQ) \
    /**/
    
    #define DO(MONAD, SEQ) \
        ([=] \
        { \
            const auto unit = MonadUnit<MONAD>{}; \
            return \
        DO_AUX( BOOST_PP_SEQ_TAIL(BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)SEQ, _END)) ) \
        })() \
    /**/

  • Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.