Какие алгоритмы трудно реализовать на функциональных языках?

Я занимаюсь функциональными языками, и я нашел некоторые алгоритмы (особенно те, которые используют динамическое программирование) сложнее писать, а иногда и менее эффективны в худшем случае во время выполнения. Существует ли класс алгоритмов, которые менее эффективны в функциональных языках с неизменяемыми переменными и побочными эффектами?

и есть ли ссылка, на которую кто-то может указать мне, что поможет с более сложными алгоритмами написания (возможно, оптимизированными shared государство)?

спасибо

3 ответов


во-первых, как вы можете или не знаете, некоторые языки, включая Haskell, реализуют совместное использование, что облегчает некоторые проблемы, которые вы могли бы подумать.

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

простой ответ на это: вещи, которые включают указатели.

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

чтобы обойти это, было сделано несколько вещей:

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

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

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

EDIT: я считаю, что суть этого вопроса касается того, как выразить вычисления функциональным образом. Однако следует отметить, что существуют способы определения вычисления состояния функциональным способом. Или, скорее, можно использовать функциональные методы для рассуждения о вычислении состояния. Например,версии ynot делает это с помощью параметризованного монада, где факты о куче (в виде логики разделения) отслеживаются монадическими связями.

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


пожалуйста помните что большинств функциональные языки позволяют некоторому понятию побочных эффектов; они могут быть нахмурены на, ограничены к местной пользе, ЕТК. но ты все еще можешь их использовать. В OCaml, Haskell, F#, Scala или Clojure вы можете использовать изменяемые массивы, если вам нужно.

Итак, если вы нашли алгоритм, для которого у вас есть формулировка с использованием изменяемых массивов, и вам нужно воспроизвести ее на одном из этих языков, просто используйте изменяемые массивы!

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

например,решето Эратосфена тривиально реализовать с изменяемыми массивами и значительно сложнее имитировать (достаточно эффективно) чисто функциональным способом: см. Мелисса О'Нил статьи для деталей.

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

(примеры использования общего доступа для оптимизации чисто функционального алгоритма см. В разделе Richard Bird и Ralf Hinze 2003 функциональная Жемчужина: общая проблема-это проблема наполовину.)


можно реализовать императивные функции с низкой асимптотической стоимостью, поэтому в абстрактном смысле нет существенных трудностей в переводе императивного кода в чисто функциональную вселенную. На практике, конечно, есть. :-) Взгляните на "чисто против нечистой сюсюкать Pippenger" и документы, которые ссылаются на это.