实际上,我会说函数编程(F#)是比C#更好的用户界面编程工具。您只需要稍微不同地考虑问题即可。
我将在第16章的函数式编程书中讨论此主题,但是有一个免费摘录,其中显示了(IMHO)您可以在F#中使用的最有趣的模式。假设您要实现矩形的绘制(用户按下按钮,移动鼠标并释放按钮)。在F#中,您可以编写如下代码:
let rec drawingLoop(clr, from) = async {
// Wait for the first MouseMove occurrence
let! move = Async.AwaitObservable(form.MouseMove)
if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then
// Refresh the window & continue looping
drawRectangle(clr, from, (move.X, move.Y))
return! drawingLoop(clr, from)
else
// Return the end position of rectangle
return (move.X, move.Y) }
let waitingLoop() = async {
while true do
// Wait until the user starts drawing next rectangle
let! down = Async.AwaitObservable(form.MouseDown)
let downPos = (down.X, down.Y)
if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then
// Wait for the end point of the rectangle
let! upPos = drawingLoop(Color.IndianRed, downPos)
do printfn "Drawn rectangle (%A, %A)" downPos upPos }
这是一种非常必要的方法(在通常的实用F#样式中),但是它避免使用可变状态来存储图形的当前状态和存储初始位置。但是,可以使它变得更加功能强大,我在硕士论文中编写了一个库来完成该任务,此库将在未来几天内在我的博客中提供。
功能性反应式编程是一种更具功能性的方法,但是我发现它很难使用,因为它依赖于相当高级的Haskell功能(例如箭头)。但是,在很多情况下它都是非常优雅的。它的局限性在于,您不能轻松地对状态机进行编码(这对于反应式程序是有用的思维模型)。使用上面的F#技术,这非常容易。