我最近发现了FP错误(试图学习Haskell),到目前为止,我对我所看到的(一流函数、惰性求值和所有其他好东西)印象深刻。我还不是专家,但我已经开始发现对基本算法进行“功能性”推理比命令式推理更容易(而且我很难回到我必须回到的地方)。

The one area where current FP seems to fall flat, however, is GUI programming. The Haskell approach seems to be to just wrap imperative GUI toolkits (such as GTK+ or wxWidgets) and to use "do" blocks to simulate an imperative style. I haven't used F#, but my understanding is that it does something similar using OOP with .NET classes. Obviously, there's a good reason for this--current GUI programming is all about IO and side effects, so purely functional programming isn't possible with most current frameworks.

My question is, is it possible to have a functional approach to GUI programming? I'm having trouble imagining what this would look like in practice. Does anyone know of any frameworks, experimental or otherwise, that try this sort of thing (or even any frameworks that are designed from the ground up for a functional language)? Or is the solution to just use a hybrid approach, with OOP for the GUI parts and FP for the logic? (I'm just asking out of curiosity--I'd love to think that FP is "the future," but GUI programming seems like a pretty large hole to fill.)


当前回答

Haskell方法似乎只是包装命令式GUI工具包(如GTK+或wxWidgets),并使用“do”块来模拟命令式样式

这并不是真正的“Haskell方法”——这只是通过命令式接口最直接地绑定到命令式GUI工具包的方法。Haskell恰好有相当突出的绑定。

有几种比较成熟的,或者更具实验性的纯函数式/声明式gui方法,主要是在Haskell中,主要使用函数式响应式编程。

一些例子是:

reflex-platform, https://github.com/reflex-frp/reflex-platform 葡萄柚,http://hackage.haskell.org/package/grapefruit-ui-gtk 无功,http://hackage.haskell.org/package/reactive-glut wxFruit, http://hackage.haskell.org/package/wxFruit reactive-banana, http://hackage.haskell.org/package/reactive-banana

对于那些不熟悉Haskell、Flapjax、http://www.flapjax-lang.org/的人来说,http://www.flapjax-lang.org/是一个基于JavaScript的函数式响应式编程的实现。

其他回答

函数式响应式编程背后的一个开放思想是让事件处理函数同时产生对事件的反应和下一个事件处理函数。因此,一个进化的系统被表示为事件处理函数的序列。

对我来说,学习Yampa成为正确理解函数生成函数的关键。有一些关于扬帕的不错的论文。我推荐The Yampa Arcade:

http://www.cs.nott.ac.uk/~nhn/Talks/HW2003-YampaArcade.pdf(幻灯片,PDF) http://www.cs.nott.ac.uk/~nhn/Publications/hw2003.pdf(全文,PDF)

在Haskell.org上有一个关于Yampa的维基页面

http://www.haskell.org/haskellwiki/Yampa

原Yampa首页:

http://www.haskell.org/yampa(不幸的是目前坏了)

我的问题是,是否可能有一种函数式的GUI编程方法?

您正在寻找的关键词是“函数式响应式编程”(FRP)。

Conal Elliott和其他一些人试图为FRP找到正确的抽象,这有点像家庭手工业。在Haskell中有几个FRP概念的实现。

您可能会考虑从Conal最近的“Push-Pull函数式响应式编程”论文开始,但是还有其他一些(更老的)实现,其中一些链接来自haskell.org网站。Conal有一个覆盖整个领域的诀窍,他的论文可以在不参考以前的情况下阅读。

为了感受如何将这种方法用于GUI开发,您可能想要看看Fudgets,虽然它在90年代中期设计,但确实为GUI设计提供了可靠的FRP方法。

Elliot关于FRP的演讲可以在这里找到。

此外,这并不是真正的答案,而是一个评论和一些想法:“功能GUI”这个术语似乎有点矛盾(纯粹性和IO在同一个术语中)。

但我模糊的理解是,函数式GUI编程是关于声明性地定义一个与时间相关的函数,该函数接受(实际)与时间相关的用户输入,并产生与时间相关的GUI输出。

换句话说,这个函数像微分方程一样声明式地定义,而不是由算法命令式地使用可变状态定义。

因此,在传统FP中,我们使用时间无关函数,而在FRP中,我们使用时间相关函数作为描述程序的构建块。

让我们考虑在弹簧上模拟一个球,用户可以与之交互。球的位置是图形输出(在屏幕上),用户推球是按键(输入)。

在FRP中描述这个仿真程序(根据我的理解)是用一个微分方程(声明性地)来完成的:加速度*质量= -弹簧拉伸*弹簧常数+用户施加的力。

这里有一个关于ELM的视频,说明了这个观点。

自从第一次提出这个问题以来,函数式响应式编程已经被Elm变得更加主流。

我建议你去http://elm-lang.org上看看,那里也有一些非常优秀的交互式教程,教你如何制作一个功能齐全的浏览器内GUI。

它允许您制作功能齐全的GUI,其中您需要自己提供的代码仅由纯函数组成。我个人认为它比各种Haskell GUI框架更容易上手。

无论您使用的是f#或OCaml这样的函数/OO混合语言,还是Haskell这样的纯函数式语言(其中副作用被归为IO单子),大多数情况下,管理GUI所需的大量工作更像是“副作用”,而不是纯函数式算法。

也就是说,已经有一些关于功能性gui的可靠研究。甚至还有一些(主要)功能性工具包,如Fudgets或FranTk。