函数式编程中的无限循环?

时间:2010-08-14 15:03:03

标签: loops recursion functional-programming

  • 我想知道:在函数式编程中可以完成无限循环吗?

示例:当使用Windows API获取Windows消息时,通常会在循环中实现。

我知道有可能创建一个将无限期地继续递归的函数。我希望这会导致堆栈溢出。

  • 是无限循环错误的功能编程思维模式?

  • 是操作系统或硬件界面的问题吗?

在我看来,它不像功能程序/ o。可以独自运行

我在编写功能程序方面有一点经验,但这一直困扰着我。 请分享您对这些问题的想法/见解

4 个答案:

答案 0 :(得分:5)

如果你使用tail recursion,你实际上有一个迭代,就像for / while循环一样。因此,我猜你可以有一个无限循环而不会出现堆栈溢出。

对于你的问题: “无限循环错误的功能编程思维模式?” 也许这会有所帮助: - While or Tail Recursion in F#, what to use when?

答案 1 :(得分: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。可以独自运行

技术上错误 - 你可以实现无限循环 - 但这样做通常没有(功能)点。除了某种IO轮询之外,为什么还需要它呢?以纯函数方式转换值应该终止有意义。

答案 2 :(得分: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

答案 3 :(得分:0)

函数式编程中大多数(如果不是全部)“无限循环”的使用可以由co-recursion建模。到目前为止,其他答案都指向了一般的递归,但是不受限制地使用递归可以说是一种糟糕的方法,因为它可能导致结构不良的代码。

纯功能程序中的绝大多数代码应该写在整个子集中,即使用结构递归或共同递归(确保终止和进展)等模式,而不是回退到一般递归。希望未来版本的GHC将包括直接支持检测Haskell的一些完整子集并发出无法证明终止或进展的代码警告。