我最近发现了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.)


当前回答

截至2016年,Haskell还有几个相对成熟的FRP框架,如Sodium和Reflex(还有Netwire)。

Manning关于函数式响应式编程的书展示了Java版本的Sodium,作为工作示例,并举例说明了FRP GUI代码库与命令式和基于Actor的方法相比是如何行为和扩展的。

最近还有一篇关于箭头化FRP的论文,以及将副作用、IO和突变纳入遵守法律的纯FRP环境的前景:http://haskell.cs.yale.edu/wp-content/uploads/2015/10/dwc-yale-formatted-dissertation.pdf。

同样值得注意的是,JavaScript框架(如ReactJS和Angular)以及其他许多框架已经或正在使用FRP或其他函数式方法来实现可伸缩和可组合的GUI组件。

其他回答

函数式编程可能从我上大学的时候就开始了,但我记得函数式编程系统的主要观点是阻止程序员产生任何“副作用”。然而,用户购买软件是由于其产生的副作用,例如更新用户界面。

所有这些其他答案都建立在函数式编程的基础上,但它们自己做出了很多设计决策。一个基本上完全由函数和简单抽象数据类型构建的库是gloss。下面是它的play函数的源类型

-- | Play a game in a window. Like `simulate`, but you manage your own input events.
play    :: Display              -- ^ Display mode.
        -> Color                -- ^ Background color.
        -> Int                  -- ^ Number of simulation steps to take for each second of real time.
        -> world                -- ^ The initial world.
        -> (world -> Picture)   -- ^ A function to convert the world a picture.
        -> (Event -> world -> world)    
                -- ^ A function to handle input events.
        -> (Float -> world -> world)
                -- ^ A function to step the world one iteration.
                --   It is passed the period of time (in seconds) needing to be advanced.
        -> IO ()

正如您所看到的,它完全通过提供具有简单抽象类型的纯函数来工作,其他库可以帮助您。

为了解决这个问题,我发布了一些我在使用f#时的想法,

http://fadsworld.wordpress.com/2011/04/13/f-in-the-enterprise-i/ http://fadsworld.wordpress.com/2011/04/17/fin-the-enterprise-ii-2/

我还计划做一个视频教程来完成这个系列,并展示f#如何在UX编程中做出贡献。

这里我只是在f#上下文中讨论。

法赫德

截至2016年,Haskell还有几个相对成熟的FRP框架,如Sodium和Reflex(还有Netwire)。

Manning关于函数式响应式编程的书展示了Java版本的Sodium,作为工作示例,并举例说明了FRP GUI代码库与命令式和基于Actor的方法相比是如何行为和扩展的。

最近还有一篇关于箭头化FRP的论文,以及将副作用、IO和突变纳入遵守法律的纯FRP环境的前景:http://haskell.cs.yale.edu/wp-content/uploads/2015/10/dwc-yale-formatted-dissertation.pdf。

同样值得注意的是,JavaScript框架(如ReactJS和Angular)以及其他许多框架已经或正在使用FRP或其他函数式方法来实现可伸缩和可组合的GUI组件。

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的函数式响应式编程的实现。