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

发布于 2024-09-14 04:55:25 字数 295 浏览 3 评论 0原文

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

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

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

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

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

在我看来,函数式程序/操作系统不能自行继续运行,

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

  • I was wondering: can infinite loops be done in functional programming?

example: when using the windows API to get windows messages, it is usually implemented in a loop.

I know it is possible to make a function that will keep going into recursion indefinitely. I expect that this will result in a stack overflow.

  • are infinite loop the wrong mind-set for functional programming ?

  • is the interface of the operating system or the hardware the problem ?

it doesn't seem to me like a functional program/o.s. could keep running by itself

I have a tiny bit of experience writing functional programs but this has always bothered me.
please share your thoughts/insights about these issues

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千鲤 2024-09-21 04:55:25

正如其他人所发布的,通过尾递归可以实现无限循环。

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

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

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

还是有道理的。考虑带有无限循环的 Windows-API 示例。那根本就不是功能性的。请记住 - 功能性意味着思考价值观(以及它们的含义)。因此,人们宁愿采用像[伪功能代码]这样的反应式/基于事件的方法,

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

所以

在我看来,功能性程序/操作系统无法自行继续运行

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

As others have posted, an infinite loop is possible through tail recursions.

E.g. loop() will effectively run as an infinite loop (in constant stack space) since the compiler can optimize out the tail-recursive call of loop at the end.

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

But

are infinite loop the wrong mind-set for functional programming ?

still got a point. Consider your Windows-API example with the infinite loop. That's anything but functional. Remember - functional means thinking in values (and what they mean). Therefore, one would rather go a reactive/event-based approach like that [Pseudo-functional code]

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

So

it doesn't seem to me like a functional program/o.s. could keep running by itself

is technically wrong - you can implement infinite loops - but there is often no (functional) point in doing so. Why should one need that except for some kind of IO polling? Transforming values in a purely functional way should terminate to be meaningful.

我喜欢麦丽素 2024-09-21 04:55:25

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

对于你的问题:“无限循环是函数式编程的错误思维方式吗?”也许这会有所帮助:
- F# 中的 while 或 tail 递归,何时使用?

If you use tail recursion, you effectively have an iteration, like a for/while loop. Therefore, I guess you can have an infinite loop without getting stack overflow.

To your question: "are infinite loop the wrong mind-set for functional programming?" maybe this will help:
- While or Tail Recursion in F#, what to use when?

隔岸观火 2024-09-21 04:55:25

如果您的编译器能够识别,您可以拥有无​​限尾递归。某些语言(例如scheme)要求编译器识别尾递归并且不为其分配堆栈空间。

编辑我并不是想不同意其他答案,但“无限”尾递归循环是与外界打交道的常见习惯用法。以下示例取自 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

我们本质上将外部世界视为

You can have infinite tail recursion if your compiler recognizes it. Some languages, e.g. scheme, require that compilers recognize tail recursion and allocate no stack space for it.

Edit I do not mean to disagree with the other answers, but "infinite" tail recursive loops with are a common idiom for dealing with the outside world. The following example is taken from Real World Haskell, and is representative of the idiom.

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

We are essentially considering the outside world as a stream.

行雁书 2024-09-21 04:55:25

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

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

Most if not all uses of "infinite loops" in functional programming can be modeled by co-recursion. Other answers so far have pointed to general recursion, but unrestricted use of recursion is arguably a poor approach as it can lead to poorly structured code.

The vast majority of code in a purely functional program should be written in the total subset, i.e. use patterns such as structural recursion or co-recursion (which ensure termination and progress) rather than falling back to general recursion. Hopefully, future versions of GHC will include direct support for detecting some total subset of Haskell and emitting warnings for code which cannot be proven to terminate or progress.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文