пример: при использовании окон API для получения сообщений окон это обычно реализуется в цикле.
Я знаю, что возможно сделать функцию, которая будет продолжать входить в рекурсию неограниченно долго. Я ожидаю, что это приведет к переполнению стека.
действительно ли бесконечный цикл является неправильным мышлением для функционального программирования?
является интерфейс операционной системы или аппаратных средств проблемой?
это не кажется мне как функциональный program/o.s., мог продолжать бежать отдельно
У меня есть крошечный бит опыта, пишущий функциональные программы, но это всегда беспокоило меня. совместно используйте свои мысли/понимание об этих проблемах
Как уже писали другие, бесконечный цикл возможен через хвостовые рекурсии ].
Например. loop ()
будет эффективно работать как бесконечный цикл (в постоянном пространстве стека), поскольку компилятор может оптимизировать хвостовой рекурсивный вызов loop
в конце.
let loop() = do {
println("foo")
loop()
}
Но
является ли бесконечный цикл неправильным мышлением для функционального программирования? В
все же есть смысл. Рассмотрим ваш пример Windows-API с бесконечным циклом. Это совсем не функционально. Помните - функциональное мышление означает мышление ценностями (и тем, что они означают). Следовательно, можно было бы использовать реактивный / основанный на событиях подход, подобный этому [Псевдофункциональный код]
(onClick form1)
|> Event.subscribe (\pt-> do { print $ "I was clicked at " ++ (show pt) })
Итак
мне это не кажется функциональной программой / программами. может продолжать работать сам по себе
технически неверно - вы можете реализовать бесконечные циклы - но часто в этом нет (функционального) смысла. Зачем это нужно, кроме какого-то опроса ввода-вывода? Преобразование ценностей чисто функциональным образом должно прекратиться, чтобы иметь смысл.
Если вы используете хвостовую рекурсию , вы фактически получаете итерацию, например цикл for / while. Следовательно, я думаю, у вас может быть бесконечный цикл без переполнения стека.
На ваш вопрос: «Неужели бесконечный цикл - неправильный образ мышления для функционального программирования?» может быть, это поможет: - Пока или хвостовая рекурсия в F #, что использовать, когда?
У вас может быть бесконечная хвостовая рекурсия , если ваш компилятор ее распознает. Некоторые языки, например схемы, требуют, чтобы компиляторы распознавали хвостовую рекурсию и не выделяли для нее место в стеке.
Править Я не хочу не соглашаться с другими ответами, но «бесконечные» хвостовые рекурсивные циклы - это обычная идиома для работы с внешним миром. Следующий пример взят из 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
По сути, мы рассматриваем внешний мир как поток .
Большинство, если не все виды использования «бесконечных циклов» в функциональном программировании можно смоделировать с помощью совместной рекурсии . Другие ответы до сих пор указывали на общую рекурсию, но неограниченное использование рекурсии, возможно, является плохим подходом, поскольку может привести к плохо структурированному коду.
Подавляющая часть кода в чисто функциональной программе должна быть написана в полном подмножестве, то есть использовать шаблоны, такие как структурная рекурсия или совместная рекурсия (которые обеспечивают завершение и прогресс), а не возвращаться к общей рекурсии. Будем надеяться, что будущие версии GHC будут включать прямую поддержку для обнаружения некоторого полного подмножества Haskell и выдачи предупреждений для кода, который не может быть доказан как завершение или прогресс.