Рекурсия
Я это как-то писал, но напишу ещё раз, бо тема поднялась.
Недостатки явной рекурсии по сравнению с комбинаторами (ага, zip3):
Юный хаскеллист, избегай явной рекурсии!
Ну и ссылочка, куда без неё!
Недостатки явной рекурсии по сравнению с комбинаторами (ага, zip3):
- Рекурсия непонятна (согласен, это субъективное).
- Обычно используется с декомпозицией, нарушая инкапусляцию.
- Всегда используется для работы с элементами, вместо работы с коллекцией (wholemeal programming).
- Цепочка вызовов проще для оптимизации.
- Сложнее нежно мною любимый equational reasoning.
Юный хаскеллист, избегай явной рекурсии!
Ну и ссылочка, куда без неё!
no subject
no subject
no subject
Сортируем пары вида (файл, зависимость) вот таким сравнением:
compareTopo (fa,depsa) (fb,depsb)
| fa `elem` depsb && fb `elem` depsa = error "cycle!"
| fa `elem` depsb = LT
| otherwise = EQ
sortDeps = sortBy compareTopo filesDeps
Первыми должны оказаться файлы без зависимостей.
Не однострочник, но близко.
no subject
Единственное, не могу сообразить, как scrap your boilerplate позволит мне одной строкой собрать из дерева все зависимости всех файлов, но верю на слово, что такое возможно.
no subject
Выхлоп: Похоже на правду.
no subject
А на циклы проверяли? Что-то меня смущает проверка на циклы. По идее зависимости должны раскрываться, но они тут раскрываться будут бесконечно в случае цикла. Банально f0 = File "f0" [f0].
no subject
no subject
no subject
В принципе, всё очевидно: двойная рекурсия спрятана в двух вложенных через map listify, которые, в свою очередь (если я ничего не путаю), просто выполняют flatten дерева.
Тогда, если можно, встречный теоретический вопрос: а как правильно в хаскеле оценить производительность алгоритма, учитывая ленивость языка и автоматическую мемоизацию? Например, в императивном языке в таком решении достаточно паскудная сложность, и двойная рекурсия будет несравнимо оптимальней.
no subject
Я, на самом деле, не большой спец по SYB. Я пользуюсь им довольно редко, только когда уж совсем нудно становится. Кстати, есть более быстрая и удобная версия SYB, называется uniplate: http://community.haskell.org/~ndm/uniplate/
Мой пример слишком простой - берём всё файлы из структуры и просеиваем через nub, убирая повторы. То есть, мы можем напороться на циклы, это раз, и мы сделаем слишком много действий, это два.
Сам listify сделан через обобщённую свёртку - gfold. В этой свёртке накапливается список - все подэлементы некоторого значения тестируются на принадлежность к File, добавляются в список и по ним делается listify, результат которого снова добавляется к результату. Чуть изменив listify, передавая ему на вход уже обнаруженные элементы, мы можем избавиться от циклов и не делать лишней работы по повторному проходу уже известных элементов.
no subject
Реквестирую решение на лиспе, т.к. haskell пока не понимаю
no subject
no subject
У вас появляется шанс поправить и понять, что не так. ;)
Поправите?
no subject
no subject
Я, откровенно говоря, не помнил алгоритма топологической сортировки.
no subject