函数式响应式编程

函数式响应式编程(FRP) 是一种编程范式，它采用函数式编程的基础部件（如map、reduce、filter等），进行响应式编程（异步数据流程编程）。FRP被用于GUI、机器人和音乐方面的编程，旨在通过显式的建模时间来简化这些问题。 函数式响应编程，自从1997年由Conal Elliott和保罗·胡达客在ICFP 97论文《函数式响应式动画》中提出以来，产生了多种形式。其多样性的一条轴线，是离散与连续语义对比。另一条轴线，是怎样让FRP系统可以动态地更改。 FRP的最早形式采用了连续的语义，旨在抽象出对程序的意义无关紧要的操作细节。这种形式的关键属性为： 建模在连续时间内变化的值，叫做“行为”，后来称为“信号”。 建模“事件”，它发生在离散的时间点上。 系统可在响应事件时被改变，通用采用术语“切换”。 从响应模型中分离出求值细节，如采样率。 这种FRP语义模型在无副作用的语言中通常采用随时间变化的连续函数。 如事件驱动FRP和Elm在0.17版本之前的那种形式，它们要求更新过程是离散的，且由事件驱动。这些形式在FRP的实践中被加以推崇，它们专注于拥有简单API的语义，比如在机器人或Web浏览器中可以被高效地实现。 在这些形式下，行为和事件的概念通常会被合并成信号，它总是拥有当前值，但会被离散地改变。 Conal Elliott在2008年已经指出，从输入到输出，这种普通的FRP模型，不太适合交互式程序。在从输入映射到输出的过程中缺乏“运行”程序的能力，可能意味着必须使用以下解决方案之一： 创建表示行动的一个数据结构，它表现为输出。行动必须被一个外部的解释器或环境来运行。它继承了最初Haskell的流式I/O的全部难点。 使用箭头（英语：Arrow (computer science)）化的FRP，和有能力实行行动的嵌入箭头。行动也必须有身份标识，比如说使得它们可以做维护各自的可变存储。采取这种办法的是Fudgets库，和更一般性的单子流函数。 最新颖的方法就是允许行动现在运行（于IO单子中），但将它们结果的接收推迟到以后。它利用了事件和IO单子之间的交互，并兼容于更加面向表达式的FRP： planNow :: Event (IO a) -> IO (Event a) 存在两种类型的FRP系统，基于推送的和基于拉取的。基于推送的系统接收事件，并将它们推过一个信号网络来达成结果。基于拉取的系统会等待对结果的需求，并逆向通过该网络检索所需求的值。 某些FRP系统例如Yampa使用采样，这里将采样推过一个信号网络。这种方法有个缺点：网络在一个计算步骤持续期间必须等待，然后才能发现输入上的变更。采样就是个基于推送的FRP示例。 Hackage上的Reactive和Etage库介入了一种叫做“推送-拉取FRP”的方式。按照这种方式，只在需求纯粹定义的流（如随时间推移的固定事件的列表）上的下一个事件时，才会构造该事件。这些纯粹定义的流的行为类似于Haskell中的惰性列表。此为基于拉取的部分。基于推送的部分会在系统外部的事件被带入系统时使用到。外部的事件会被推送给消费者，这样它们就可以在它发布的瞬间找到该事件。 Yampa，是一个箭头化、高效的、纯Haskell实现，支持SDL、SDL2、OpenGL和HTML DOM。 reflex，是一个高效的，用Haskell实现的推送/拉取式FRP，主要宿主是浏览器/DOM、SDL和Gloss。 reactive-banana，是一个用Haskell实现的目标不可知的推送式FRP。 netwire和varying，是箭头化的，用Haskell实现的拉取式FRP。 Flapjax，是一个用JavaScript实现的行为/事件式FRP。 React，是用于函数式响应编程的一个OCaml模块。 Sodium，是独立于UI框架的推送式FRP实现，支持多种编程语言比如Java、TypeScript和C#。 ReactiveX（英语：ReactiveX），由它的JavaScript实现rxjs而流行，是实现函数式响应式编程的综合性跨平台范型，将数据当作可观测者的流来处理。 Dunai，是支持类和箭头化FPR的，使用单子流函数的一个Haskell的快速实现。 Elm编程语言，曾经支持FRP，但是现在以不同的模式替代了它。 Ur编程语言，浏览器客户端包括了函数式响应式编程设施。 增量计算 串流处理 Elliott, Conal; Hudak, Paul, Functional Reactive Animation, ICFP, 1997 [2018-04-13], （原始内容存档于2020-11-11） . Nilsson, Henrik; Courtney, Antony; Peterson, John, Functional Reactive Programming, Continued (PDF), Haskell Workshop (PDF)使用|format=需要含有|url= (帮助) (2), Feb 2011 [2002] [2018-04-13], （原始内容 (PDF)存档于2017-10-10） . Courtney, Antony; Elliott, Conal, Genuinely Functional User Interfaces, Haskell Workshop, Yale, Feb 2011 [2001] [2018-04-13], （原始内容存档于2022-04-13） . Taha, Walid; Wan, Zhanyong; Hudak, Paul, Event-Driven FRP, PADL, Yale, 2002 [2021-03-02], （原始内容存档于2021-02-10） . Czaplicki, Evan; Chong, Stephen, Asynchronous Functional Reactive Programming for GUIs, PLDI, Harvard, 2013 [2018-04-13], （原始内容存档于2018-11-09） . Wan, Zhanyong; Taha, Walid; Hudak, Paul, Real-Time FRP, ICFP (PDF) (1), Feb 2011 . Why classic FRP does not fit interactive behavior. [2018-04-13]. （原始内容存档于2015-07-24）.  Alan Borning1CSE 505I/O in Purely Functional Languages (PDF). [2018-04-13]. （原始内容存档 (PDF)于2016-05-28）.  The Fudgets Thesis on WWW. [2018-04-13]. （原始内容存档于2020-01-24）.  Perez, Ivan; Barenz, Manuel; Nilsson, Henrik, Functional Reactive Programming, Refactored, Haskell Symposium (PDF), July 2016 [2021-03-02], （原始内容存档 (PDF)于2017-05-18） . Atze van der Ploeg; Koen Claessen. Practical Principled FRP－Forget the past, change the future, FRPNow!. [2021-03-04]. （原始内容存档于2020-04-25）.  Yampa. [2021-03-02]. （原始内容存档于2021-03-01）.  reflex. [2018-04-13]. （原始内容存档于2020-11-11）.  reactive-banana. [2018-04-13]. （原始内容存档于2020-11-11）.  netwire. [2018-04-13]. （原始内容存档于2020-10-20）.  varying. [2018-04-13]. （原始内容存档于2020-11-12）.  React. [2021-03-02]. （原始内容存档于2020-12-24）.  Sodium. [2021-03-02]. （原始内容存档于2020-12-24）.  rxjs. [2021-03-02]. （原始内容存档于2021-05-17）.  Dunai. [2021-03-02]. （原始内容存档于2021-05-24）.  Czaplicki, Evan, Elm: Concurrent FRP for Functional GUIs (PDF) (thesis), Harvard, Apr 2012 [2021-03-02], （原始内容存档 (PDF)于2021-04-16） . Czaplicki, Evan. A Farewell to FRP. elm. [14 July 2018]. （原始内容存档于2019-05-31）.  cellx（页面存档备份，存于互联网档案馆） – 一个 JavaScript 实现的超快速反应式库 Haskell 相关的 FRP（页面存档备份，存于互联网档案馆） 研究 "Deprecating the Observer Pattern with Scala.React（页面存档备份，存于互联网档案馆）," – Scala.React, 一个 FRP 的 Scala 实现 probability of living chart example - 使用ReactiveChart FRP 的无毛刺实现，详见文档 https://web.archive.org/web/20170927112527/https://reactivechart.com/knowledge/reactive/ What is (functional) reactive programming?（页面存档备份，存于互联网档案馆） – Stack Overflow 的问答