代码之家  ›  专栏  ›  技术社区  ›  symbiont

函数编程中的无限循环?

  •  8
  • symbiont  · 技术社区  · 16 年前
    • 我想知道:函数式编程中能完成无限循环吗?

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

    我知道有可能使一个函数无限期地进入递归。我预计这将导致堆栈溢出。

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

    • 操作系统或硬件的接口是否存在问题?

    在我看来,一个功能性的程序/O.S.似乎不能自己继续运行。

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

    4 回复  |  直到 16 年前
        1
  •  4
  •   Dario    16 年前

    正如其他人所说,一个无限循环 可能通过 tail recursions .

    例如。 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轮询之外还需要它?以纯粹的功能性方式转换值应该是有意义的。

        2
  •  5
  •   Community Mohan Dere    9 年前

    如果你使用 tail recursion 您实际上有一个迭代,比如for/while循环。因此,我想您可以有一个无限循环,而不会得到堆栈溢出。

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

        3
  •  1
  •   deinst    16 年前

    你可以拥有无限 tail recursion 如果编译器能识别它。有些语言,例如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
    

    我们基本上认为外部世界是 stream .

        4
  •  0
  •   func    16 年前

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

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

    推荐文章