函数式反应式编程

维基百科,自由的百科全书
跳到导航 跳到搜索

函数式反应式编程(FRP) 是一种采用函数式编程的基础部件(如 mapreduce、filter 等)进行反应式编程异步数据流编程)的编程范式。FRP 被用于GUI机器人和音乐方面的编程,旨在通过明确时间模型来简化这些问题。

FRP 的形式[编辑]

自 1997 年 FRP 被提出以来,它产生了多种形式。[1]其中一条多样性的坐标轴是语义从离散到连续。 另一条轴是 FRP 系统可以如何被动态地更改。[2]

离散[编辑]

如事件驱动 FRP 和 Elm 0.17 版本之前的形式那样,它们要求更新过程是离散的,且由事件驱动。[3] 这些形式在 FRP 的实践中被加以推崇,它们专注于拥有简单 API 的语义,可以在如机器人学或 Web 浏览器中被高效地实现。[4]

在这些形式下,行为和事件的概念通常会被组合成总是拥有当前值的信号,但是它会被离散地改变。[5]

连续[编辑]

FRP 的最早形式采用了连续的语义,旨在抽象出对程序的意义无关紧要的操作细节。[6] 这种形式的关键属性为:

  • 建模值在连续时间内变化,叫做“行为”,后称为“信号”。
  • 建模“事件”发生在离散的时间点上。
  • 系统可在相应事件时被改变,通用术语为“切换”。
  • 从反应模型中分离出求值细节,如采样率。

这种 FRP 的语义模型在无副作用的语言中通常是随时间变化的连续函数。[7]

交互式 FRP[编辑]

需要被指出的是,普通的 FRP 模型,从输入到输出都不太适合交互式程序。[8] 在从输入映射到输出的过程中缺乏“运行”程序的能力可能意味着必须使用以下解决方案之一:

  • 创建一个用于输出的数据结构来表示活动。活动必须被一个外部的解释器或环境来运行。它继承了最初 Haskell 的流式 I/O 的全部难点。[9]
  • 使用箭头化的 FRP 并嵌入能够处理动作的箭头。活动也必须要有ID,以便让它们分别维护不可变存储之类的东西。这就是 Fudgets 库采取的办法。[10]
  • 最新颖的方法就是允许活动运行在现在(在 IO 单子中)但将它们结果的接收推迟到之后。[11] 它采用了事件 Event 和 IO 单子之间的交互,并与更加面向表达式的 FRP 兼容:
planNow :: Event (IO a) -> IO (Event a)

实现问题[编辑]

存在两种类型的 FRP 系统,基于推送的和基于拉取的。基于推送的系统接收事件并将它们推过一个信号网络来达到某种结果。基于拉取的系统会等待结果请求,并逆向通过该网络来取回请求的结果。

某些 FRP 系统例如 Yampa 使用采样。在一个定期内,采样被推过一个信号网络。这种方法有两个缺点:在一个定期内处理样本的计算量会非常大,而且网络必须在等待采样区间的间隔时找出输入的更改。采样就是个基于推送的 FRP 示例。

Hackage 上的 Reactive 和 Etage 库介绍了一种叫做“推送-拉取 FRP” 的方式,它将基于推送和基于拉取的 FRP 最好的部分结合在了一起。按照这种方式,只有在定义纯粹的流上(如一系列时间固定的事件)的下一个事件被请求时,才会构造该事件。这些定义纯粹的流的行为类似于 Haskell 中的惰性列表。此为基于拉取的部分。基于推送的部分会在系统外部的事件被带入系统中时才会使用。外部的事件会被推送给消费者,这样它们就可以在它发布的瞬间找到该事件。

实现[编辑]

  • reflex 是一个高效的,用 Haskell 实现的推送/拉取式 FRP,主要用于浏览器/DOM、SDL 和 Gloss
  • reactive-banana 是一个用 Haskell 实现的目标不可知的推送式 FRP
  • netwire 和 varying 是被箭头化的,用 Haskell 实现的拉取式 FRP
  • Flapjax 是一个用 JavaScript 实现的行为/事件式 FRP

另请参阅[编辑]

参考来源[编辑]

  1. ^ Czaplicki, Evan, Elm: Concurrent FRP for Functional GUIs (PDF) (thesis), Harvard, Apr 2012 .
  2. ^ Nilsson, Henrik; Courtney, Antony; Peterson, John, Functional Reactive Programming, Continued (PDF), Haskell Workshop (PDF) (2), Feb 2011 [2002] .
  3. ^ Taha, Walid; Wan, Zhanyong; Hudak, Paul, Event-Driven FRP, PADL (PDF), Yale, 2002, (原始内容 (PDF)存档于2013-09-28) .
  4. ^ Czaplicki, Evan; Chong, Stephen, Asynchronous Functional Reactive Programming for GUIs, PLDI, Harvard, 2013 .
  5. ^ Wan, Zhanyong; Taha, Walid; Hudak, Paul, Real-Time FRP, ICFP (PDF) (1), Feb 2011 .
  6. ^ Elliott, Conal; Hudak, Paul, Functional Reactive Animation, ICFP, 1997 .
  7. ^ Courtney, Antony; Elliott, Conal, Genuinely Functional User Interfaces (PDF), Haskell Workshop, Yale, Feb 2011 [2001] .
  8. ^ http://conal.net/blog/posts/why-classic-frp-does-not-fit-interactive-behavior
  9. ^ https://courses.cs.washington.edu/courses/cse505/01au/functional/functional-io.pdf
  10. ^ http://www.cse.chalmers.se/~hallgren/Thesis/
  11. ^ 存档副本 (PDF). [2015年7月24日]. (原始内容 (PDF)存档于2015年7月1日). 

外部链接[编辑]