【问题标题】:infinite loop in functional programming?函数式编程中的无限循环?
【发布时间】:2011-03-29 20:57:52
【问题描述】:
  • 我想知道:函数式编程中可以实现无限循环吗?

例子:使用windows API获取windows消息时,一般是循环实现的。

我知道可以创建一个无限循环的函数。我预计这会导致堆栈溢出。

  • 无限循环是函数式编程的错误思维方式吗?

  • 是操作系统的接口还是硬件的问题?

在我看来,它不像一个功能性程序/o.s。可以自行运行

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

【问题讨论】:

  • 尝试谷歌搜索“尾递归”。
  • 感谢大家的意见

标签: loops recursion functional-programming


【解决方案1】:

正如其他人所发布的,通过tail recursions 可以实现无限循环

例如loop() 将有效地作为无限循环运行(在恒定的堆栈空间中),因为编译器可以在最后优化 loop 的尾递归调用。

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

但是

无限循环是函数式编程的错误思维方式吗?

还是有道理的。考虑带有无限循环的 Windows-API 示例。那不是功能性的。请记住 - 功能意味着思考价值观(以及它们的含义)。因此,人们宁愿采用类似 [Pseudo-functional code] 的响应式/基于事件的方法

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

所以

在我看来,它不像一个功能性程序/o.s。可以自行运行

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

【讨论】:

  • 有趣。我不认为函数式编程可以摆脱无限递归(很高兴知道)。感谢您提供的信息和您的见解。我喜欢反应式编程的想法。
  • 举个例子说明为什么要这样做:程序的核心通常最好表示为世界状态中潜在的无限转换序列(例如,吃豆人即将吃药, 吃豆人是一步,吃了药丸,等等)。根据我的经验,这也是最常见的无限循环情况。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    如果您的编译器识别它,您可以拥有无​​限的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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-22
        • 2013-10-12
        • 1970-01-01
        • 1970-01-01
        • 2019-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多