2010-08-14 2 views
8
  • Мне было интересно: могут ли бесконечные циклы работать в функциональном программировании?

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

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

  • бесконечный цикл неправильного набора разума для функционального программирования?

  • является интерфейсом операционной системы или аппаратного обеспечения проблемы?

Это не похоже на функциональную программу/o.s. может продолжать работать сам по себе

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

+2

Попробуйте «рекурсию хвоста». – sje397

+0

спасибо за ваш вклад все – symbiont

ответ

4

Как уже писал, бесконечный цикл является возможно через tail recursions.

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

let loop() = do { 
    println("foo") 
    loop() 
} 

Но

бесконечны цикл неправильно мышление для функционального программирования?

все еще получил очко. Рассмотрим пример Windows-API с бесконечным циклом. Это ничего, кроме функционального.Помните - функциональный означает мышление в значениях, что означает). Таким образом, можно было бы лучше пойти реактивную/на основе событий подобный подход [Псевдо-функциональный код]

(onClick form1) 
|> Event.subscribe (\pt-> do { print $ "I was clicked at " ++ (show pt) }) 

Так

это не кажется мне, как функционального программы/o.s. может продолжать работать сам по себе

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

+0

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

+0

В качестве примера, почему вы это сделаете: ядро ​​программы часто лучше всего представлено как потенциально бесконечная последовательность преобразований в мире (например, Pac-Man собирается съесть таблетку, Pac-Man - это один шаг и съел пилюлю и т. д.). Это также самый распространенный случай для бесконечных циклов в моем опыте. – Chuck

1

У вас может быть бесконечный tail recursion, если ваш компилятор его распознает. Некоторые языки, например. схема, требуют, чтобы компиляторы распознавали хвостовую рекурсию и не выделяли для нее пространства стека.

Редактировать Я не хочу не соглашаться с другими ответами, но «бесконечные» хвостовые рекурсивные циклы - это общая идиома для общения с внешним миром. Следующий пример берется из Real World Haskell и является представителем идиомы.

mainloop :: Handle -> Handle -> IO() 
mainloop inh outh = 
    do ineof <- hIsEOF inh 
     if ineof 
      then return() 
      else do inpStr <- hGetLine inh 
        hPutStrLn outh (map toUpper inpStr) 
        mainloop inh outh 

Мы по существу рассматриваем внешний мир как stream.

5

Если вы используете tail recursion, у вас есть итерация, как цикл for/while. Поэтому, я думаю, вы можете иметь бесконечный цикл без переполнения стека.

На ваш вопрос: «Бесконечный цикл неправильного набора разума для функционального программирования?» может быть, это поможет: - While or Tail Recursion in F#, what to use when?

0

Большинство, если не все виды использования «бесконечных циклов» в функциональном программировании могут быть смоделированы co-recursion. Другие ответы до сих пор указывали на общую рекурсию, но неограниченное использование рекурсии, возможно, является плохим подходом, поскольку это может привести к плохо структурированному коду.

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

Смежные вопросы