![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Я это как-то писал, но напишу ещё раз, бо тема поднялась.
Недостатки явной рекурсии по сравнению с комбинаторами (ага, zip3):
Юный хаскеллист, избегай явной рекурсии!
Ну и ссылочка, куда без неё!
Недостатки явной рекурсии по сравнению с комбинаторами (ага, zip3):
- Рекурсия непонятна (согласен, это субъективное).
- Обычно используется с декомпозицией, нарушая инкапусляцию.
- Всегда используется для работы с элементами, вместо работы с коллекцией (wholemeal programming).
- Цепочка вызовов проще для оптимизации.
- Сложнее нежно мною любимый equational reasoning.
Юный хаскеллист, избегай явной рекурсии!
Ну и ссылочка, куда без неё!
no subject
Date: 2012-11-30 01:53 pm (UTC)no subject
Date: 2013-10-04 05:24 pm (UTC)no subject
Date: 2012-11-30 01:56 pm (UTC)no subject
Date: 2012-11-30 02:27 pm (UTC)no subject
Date: 2012-11-30 03:45 pm (UTC)Вот об этом было бы интересно подробнее послушать.
no subject
Date: 2012-11-30 03:58 pm (UTC)Зачем нам алгебраические структуры в самом деле? Чтобы их использовать! :-)
Ну, и в нагрузку ещё немножко про дизайн (http://lukepalmer.wordpress.com/2008/07/18/semantic-design/) от Люка Палмера (правда, это оффтопик).
no subject
Date: 2012-11-30 04:07 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-11-30 04:48 pm (UTC)Кажется, ссылка потерялась, и ЖЖ вместо неё подставил адрес текущей страницы.
no subject
Date: 2012-11-30 05:20 pm (UTC)no subject
Date: 2012-11-30 06:45 pm (UTC)no subject
Date: 2012-11-30 07:06 pm (UTC)(no subject)
From:(no subject)
From:no subject
Date: 2012-11-30 07:14 pm (UTC)И можно на ты.
no subject
Date: 2012-11-30 08:03 pm (UTC)Структурная рекурсия, это один простой паттерн, легко укладывающийся в довольно простой Тьюринг-худой язык.
А значит, имеем простой и предсказуемый reasoning.
Что вполне подтверждается на практике.
Общая рекурсия заставляет думать в рамках уже Тьюринг-полноты, что в общем случае, неразрешимо даже теоретически, а не то, чтобы уложилось человеку в голову.
Конечно же, при реальном программировании, возникает ряд "паттернов" (навроде отслеживания разборки значения индуктивного типа), иначе бы было очень сложно сделать что-то.
Ну вот, структурная рекурсия, это один из таких паттернов — простой, чОтко формализованный и весьма общий.
no subject
Date: 2012-11-30 08:55 pm (UTC)no subject
Date: 2012-12-01 07:22 am (UTC)Ему от этого становится лучше, да! ;-)
no subject
Date: 2012-11-30 08:39 pm (UTC)no subject
Date: 2012-11-30 09:05 pm (UTC)2. Этот пост возник из-за этой дискуссии (http://levgem.livejournal.com/420910.html?thread=5124654#t5124654). Т.е. "как заменить" уже есть.
Не стоит заменять. Если нужно, скажем, делать разбор двух структур по условию, то я пишу рекурсивный код. Пример: merge двух сортированных списков.
no subject
Date: 2012-11-30 09:54 pm (UTC)no subject
Date: 2012-11-30 09:31 pm (UTC)В качестве возможного примера могу предложить Omega monad: http://hackage.haskell.org/package/control-monad-omega
Комбинатор рекурсивной обработки потенциально бесконечных списков с гарантированным перечислением всех элементов.
no subject
Date: 2012-11-30 09:53 pm (UTC)Где, грубо говоря, file -- это исходник, а module -- директория. Нужно написать функцию, которая применит функцию компиляции к каждому исходному файлу, причём в правильном порядке, с учётом что от чего зависит.
Для данного примера порядок может быть таким: f1, f2, f4, f5, f3, f6, f0, f7.
В идеале ещё бы обнаружить циклические зависимости.
Как это сделать двойной рекурсией -- очевидно, а вот комбинаторного решения я придумать не могу.
no subject
Date: 2012-11-30 10:09 pm (UTC)http://www.haskell.org/haskellwiki/Scrap_your_boilerplate
(есть ещё более навороченные и/или удобные варианты, более поздние)
Например, одной строкой можно получить все файлы. Другой - все зависимости. Отображение (map compile) на файлы даст компиляцию и тп.
Наверное, это ближе всего к нужному тебе.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-11-30 11:51 pm (UTC)Он на ней деньги собирался зарабатывать. ;)
no subject
Date: 2012-12-01 12:17 am (UTC)Идея такая:
1. Строим список пар (имя объекта, непосредственные зависимости). Для файла это зависимости, для модуля - имена компонентов.
2. Строим дерево зависимостей, т.е. разворачиваем непосредственные зависимости.
3. Сортируем очевидным образом (зависящий идёт позже, если независимы - по имени)
4. Вуаля
Код без учёта циклических зависимостей: http://hpaste.org/78574
Для учёта идея проста, мы храним "родителей" и смотрим, чтобы текущий от них не зависел: http://hpaste.org/78575
Update
Я был не прав в пункте 3, сортировать не нужно. Вот конечный результат: http://hpaste.org/78585
(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-12-01 11:11 am (UTC)http://hpaste.org/78589 (http://hpaste.org/78589)
(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-12-01 10:25 pm (UTC)но для того, чтобы избежать явной рекурсии это не обязательно. например, в данном случае берем рекурсивный алгоритм из википедии (http://en.wikipedia.org/wiki/Topological_sort, второй) и пишем его в лоб: http://hpaste.org/78601
основная функция получилась так:
Код сурово императивный, что видно по foldr, но хотя бы нет явной структурной рекурсии.
Как известно, вместо рекурсии можно использовать цикл с очередью (http://hpaste.org/78602):
Код по-прежнему императивный, но явной рекурсии больше нет. Она спрятана в until и foldr.
Если все немного обобщить (разрешить зависимости и на уровне модулей, чтобы структура была более симметричная) и причесать, то можно избавиться от рекурсии и во flatten, перенеся ее в общий комбинатор foldTree: http://hpaste.org/78603