Là lập trình GUI chức năng có thể? [đóng cửa]


404

Gần đây tôi đã bắt gặp lỗi FP (cố gắng học Haskell) và tôi thực sự ấn tượng với những gì tôi đã thấy cho đến nay (các chức năng hạng nhất, đánh giá lười biếng và tất cả các tính năng khác). Tôi chưa phải là chuyên gia, nhưng tôi đã bắt đầu thấy lý do "chức năng" dễ dàng hơn so với các thuật toán cơ bản (và tôi gặp khó khăn khi quay trở lại nơi tôi phải đến).

Tuy nhiên, một lĩnh vực mà FP hiện tại dường như không ổn định là lập trình GUI. Cách tiếp cận Haskell dường như chỉ bao gồm các bộ công cụ GUI bắt buộc (như GTK + hoặc wxWidgets) và sử dụng các khối "làm" để mô phỏng một kiểu bắt buộc. Tôi đã không sử dụng F #, nhưng sự hiểu biết của tôi là nó làm điều gì đó tương tự bằng cách sử dụng OOP với các lớp .NET. Rõ ràng, có một lý do chính đáng cho việc này - lập trình GUI hiện tại là tất cả về IO và các tác dụng phụ, vì vậy lập trình chức năng hoàn toàn không thể thực hiện được với hầu hết các khung hiện tại.

Câu hỏi của tôi là, có thể có một cách tiếp cận chức năng để lập trình GUI? Tôi đang gặp khó khăn khi tưởng tượng điều này sẽ trông như thế nào trong thực tế. Có ai biết bất kỳ khuôn khổ nào, thử nghiệm hay nói cách khác, hãy thử loại điều này (hoặc thậm chí bất kỳ khung nào được thiết kế từ đầu cho một ngôn ngữ chức năng) không? Hoặc là giải pháp để chỉ sử dụng một phương pháp lai, với OOP cho các phần GUI và FP cho logic? (Tôi chỉ đang tò mò thôi - Tôi rất muốn nghĩ rằng FP là "tương lai", nhưng lập trình GUI có vẻ như là một lỗ hổng khá lớn để lấp đầy.)


7
Nhìn vào GUI trong Common Lisp và OCaml, tôi sẽ nói rằng, nhiều khả năng, sự lười biếng của Haskell gây ra vấn đề.
new123456

5
@ new123456 Lisp thông thường không phải là ngôn ngữ chức năng, nó hoạt động với dữ liệu có thể thay đổi và bao gồm các tác dụng phụ
Cà phê điện

3
@ElectricCoffee Lisp là một ngôn ngữ cực kỳ linh hoạt có khả năng được sử dụng trong nhiều phong cách khác nhau và nhiều người chọn sử dụng Lisp theo phong cách chức năng.
chrismamo1

8
Từ kinh nghiệm của tôi (mặc dù tôi vẫn đang cố gắng tin vào nó và học hỏi thêm) FRP thực sự đạt đến giới hạn với lập trình GUI; nó đẹp và thanh lịch cho 80% các trường hợp sử dụng nhưng các widget phong phú đòi hỏi phải kiểm soát rất chính xác trạng thái bên trong của chúng (ví dụ: hộp tổ hợp tìm kiếm, v.v.) và FRP chỉ cản trở bạn. Không bắt buộc không phải lúc nào cũng xấu xa; cố gắng giảm thiểu số lượng mã bắt buộc là tốt nhưng loại bỏ 100% của nó? Vẫn chưa thấy nó hoạt động để phát triển UI không tầm thường.
AlexG

8
@ElectricCoffee "Mặc dù Lisp thông thường không phải là ngôn ngữ chức năng". Lisp là mẹ của tất cả các ngôn ngữ chức năng. Ý bạn là Lisp không thuần khiết.
Jon Harrop

Câu trả lời:


184

Cách tiếp cận Haskell dường như chỉ bao gồm các bộ công cụ GUI bắt buộc (như GTK + hoặc wxWidgets) và sử dụng các khối "do" để mô phỏng kiểu bắt buộc

Đó thực sự không phải là "cách tiếp cận Haskell" - đó chỉ là cách bạn liên kết với các công cụ GUI bắt buộc trực tiếp nhất - thông qua một giao diện bắt buộc. Haskell chỉ xảy ra để có ràng buộc khá nổi bật.

Có một số cách tiếp cận khai thác vừa phải, hoặc thử nghiệm hoàn toàn theo chức năng / khai báo đối với GUI, chủ yếu ở Haskell, và chủ yếu sử dụng lập trình phản ứng chức năng.

Một số ví dụ:

Đối với những người bạn không quen thuộc với Haskell, Flapjax, http://www.flapjax-lang.org/ là một triển khai lập trình phản ứng chức năng trên JavaScript.


32
Xem bài viết của Conal Elliott về trái cây để có mô tả sâu sắc, sâu sắc về kỹ thuật và các quyết định: conal.net/ con / genuinely-feftal-guis.pdf Tôi đã thực hiện lập trình GUI hoàn toàn theo chức năng này trong vài tháng nay . Tôi yêu nó, nó là một sự giải thoát dễ chịu từ địa ngục spaghetti của lập trình UI bắt buộc, điều này dường như tồi tệ hơn về mặt này so với hầu hết các chương trình bắt buộc.
luqui

44
Tôi 100% đồng ý với điều này. Để làm cho nó rõ ràng: lý do tại sao các bộ công cụ GUI hiện có thường được sử dụng là vì chúng tồn tại. Lý do tại sao các giao diện với chúng có xu hướng bắt buộc và không tinh khiết là bởi vì các bộ công cụ có xu hướng bắt buộc và không tinh khiết. Lý do tại sao các bộ công cụ có xu hướng bắt buộc và không tinh khiết là bởi vì các hệ điều hành mà chúng phụ thuộc vào có xu hướng bắt buộc và không trong sạch. Tuy nhiên, về cơ bản không có gì đòi hỏi bất kỳ thứ gì trong số này là không chắc chắn: có các ràng buộc chức năng cho các bộ công cụ đó, có các bộ công cụ chức năng, thậm chí còn có các hệ điều hành chức năng.
Jörg W Mittag

16
Tất cả chỉ là vấn đề của sự lười biếng. (Ý định chơi chữ xấu.)
Jörg W Mittag

10
Một ngày nào đó tất cả thiết kế GUI sẽ được triển khai thông qua WYSIWYG, với logic được triển khai theo chức năng. Đây là dự đoán của tôi.
BlueRaja - Daniel Pflughoeft

24
Các đề cập luqui giấy dường như đã chết. Tuy nhiên, có một liên kết hoạt động trên trang web của Conal Elliott: conal.net/ con / genuinely
feftal

74

Câu hỏi của tôi là, có thể có một cách tiếp cận chức năng để lập trình GUI?

Các từ khóa bạn đang tìm kiếm là "lập trình phản ứng chức năng" (FRP).

Conal Elliott và một số người khác đã tạo ra một chút công nghiệp tiểu thủ khi cố gắng tìm ra sự trừu tượng đúng đắn cho FRP. Có một số triển khai các khái niệm FRP trong Haskell.

Bạn có thể xem xét bắt đầu với bài viết "Lập trình phản ứng chức năng đẩy" gần đây nhất của Conal , nhưng có một số cách triển khai (cũ hơn) khác, một số được liên kết từ trang web haskell.org . Conal có một sở trường để bao quát toàn bộ miền, và giấy của anh ta có thể được đọc mà không cần tham khảo những gì đến trước.

Để cảm nhận về cách tiếp cận này có thể được sử dụng để phát triển GUI, bạn có thể muốn xem Fudgets , trong khi nó đang hơi lâu trong những ngày này, được thiết kế vào giữa những năm 90, trình bày một cách tiếp cận FRP vững chắc để thiết kế GUI.


Tôi muốn thêm sự gia tăng của việc sử dụng "Phần mở rộng phản ứng" (Thư viện FRP; tuy nhiên, không phải là FP) ban đầu được viết cho C # và sau đó được chuyển sang Java (RxJava) và JavaScript (RxJS) và các ngôn ngữ khác nhau. Kiểm tra Reactivex.ioAt điểm, Angular 2 sử dụng RxJS rộng rãi.
srph

63

Windows Presentation Foundation là một bằng chứng cho thấy phương pháp chức năng hoạt động rất tốt cho lập trình GUI. Nó có nhiều khía cạnh chức năng và mã WPF "tốt" (tìm kiếm mẫu MVVM) nhấn mạnh cách tiếp cận chức năng hơn mệnh lệnh. Tôi có thể mạnh dạn tuyên bố rằng WPF là bộ công cụ GUI chức năng trong thế giới thực thành công nhất :-)

WPF mô tả giao diện Người dùng trong XAML (mặc dù bạn có thể viết lại giao diện đó thành chức năng tìm kiếm C # hoặc F #), vì vậy để tạo một số giao diện người dùng bạn sẽ viết:

<!-- Declarative user interface in WPF and XAML --> 
<Canvas Background="Black">
   <Ellipse x:Name="greenEllipse" Width="75" Height="75" 
      Canvas.Left="0" Canvas.Top="0" Fill="LightGreen" />
</Canvas>

Hơn nữa, WPF cũng cho phép bạn mô tả khai báo hoạt hình và phản ứng đối với các sự kiện bằng cách sử dụng một bộ thẻ khai báo khác (một lần nữa, điều tương tự có thể được viết dưới dạng mã C # / F #):

<DoubleAnimation
   Storyboard.TargetName="greenEllipse" 
   Storyboard.TargetProperty="(Canvas.Left)"
   From="0.0" To="100.0" Duration="0:0:5" />

Trên thực tế, tôi nghĩ rằng WPF có nhiều điểm tương đồng với FRP của Haskell (mặc dù tôi tin rằng các nhà thiết kế WPF không biết về FRP và điều đó thật đáng tiếc - đôi khi WPF cảm thấy hơi kỳ lạ và không rõ ràng nếu bạn đang sử dụng chức năng quan điểm).


12
Trong khi bản chất XAML rất khai báo, MVVM có thực sự khuyến khích một phong cách lập trình chức năng không? Toàn bộ khái niệm về một mô hình khung nhìn, có công việc là theo dõi trạng thái của khung nhìn (và thực hiện một giao diện được gọi là INotifyPropertyChangedcủa tất cả mọi thứ), dường như đối nghịch với FP đối với tôi. Tôi chắc chắn không phải là chuyên gia về FP và có lẽ tôi đang tập trung quá nhiều vào khía cạnh bất biến trái ngược với khía cạnh khai báo, nhưng tôi gặp khó khăn khi xem mẫu MVVM (như thường được sử dụng) là một ví dụ về FP.
devuxer

1
@devuxer Tôi sẽ tranh luận rằng nó làm. Tôi không nghĩ bất cứ ai thực sự sẽ sử dụng FP cho mã bất biến nghiêm ngặt. Thay vào đó, bạn quyết định ranh giới khả năng biến đổi của mình ở đâu và hoạt động bất biến trên tất cả các cấp độ khác - trong trường hợp này, mọi người đều có thể cho rằng trạng thái là bất biến, ngoại trừ phần nhỏ bé đó thực sự làm thay đổi trạng thái. Nó tương tự như cách HTML hoạt động - vâng, bạn đã có DOM bất biến, nhưng bất cứ khi nào bạn điều hướng, bạn vẫn phải xây dựng một cái mới. INotifyPropertyChangedchỉ là một chức năng cập nhật mà bạn chuyển đến bất cứ nơi nào bạn cần để xử lý các bản cập nhật GUI - đó là một sửa chữa độ trễ.
Luaan

3
Steven Pemberton đã viết 2 bài đăng tuyệt vời trên F # và WPF, Suy nghĩ của anh ấy về phát triển WPF với F # vào cuối bài thứ hai thêm vào cuộc thảo luận này. Hai ví dụ khác cũng khiến tôi tò mò là việc sử dụng bộ điều khiển chức năng trong MVVM hướng sự kiện và sử dụng các hiệp hội phân biệt và đệ quy để xây dựng giao diện đơn giản trong bản demo điều khiển WPF của Flying Frog Consultingancy.
Funk

29

Tôi thực sự sẽ nói rằng lập trình chức năng (F #) là công cụ tốt hơn cho lập trình giao diện người dùng so với C #. Bạn chỉ cần nghĩ về vấn đề một chút khác nhau.

Tôi thảo luận về chủ đề này trong cuốn sách lập trình chức năng của tôi trong Chương 16, nhưng có một đoạn trích miễn phí , cho thấy (IMHO) mẫu thú vị nhất mà bạn có thể sử dụng trong F #. Giả sử bạn muốn thực hiện vẽ hình chữ nhật (người dùng nhấn nút, di chuyển chuột và nhả nút). Trong F #, bạn có thể viết một cái gì đó như thế này:

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 }

Đây là một cách tiếp cận rất bắt buộc (theo kiểu F # thực dụng thông thường), nhưng nó tránh sử dụng trạng thái có thể thay đổi để lưu trữ trạng thái hiện tại của bản vẽ và để lưu trữ vị trí trong cơ thể. Nó có thể được thực hiện thậm chí nhiều chức năng hơn, tôi đã viết một thư viện làm điều đó như là một phần của luận án thạc sĩ của tôi, sẽ có sẵn trên blog của tôi trong vài ngày tới.

Chức năng lập trình phản ứng chức năng là một cách tiếp cận chức năng nhiều hơn, nhưng tôi thấy nó hơi khó sử dụng vì nó phụ thuộc vào các tính năng Haskell khá tiên tiến (như mũi tên). Tuy nhiên, nó rất thanh lịch trong một số lượng lớn các trường hợp. Hạn chế của nó là bạn không thể dễ dàng mã hóa một máy trạng thái (là mô hình tinh thần hữu ích cho các chương trình phản ứng). Điều này rất dễ dàng bằng cách sử dụng kỹ thuật F # ở trên.


7
+1 Điều này phản ánh trải nghiệm của chúng tôi, khi đã viết một số GUI sản xuất trong F # bằng cách sử dụng các thư viện kết hợp và IObservable.
Jon Harrop

Nhận xét về FRP có thay đổi kể từ khi giới thiệu các phần mở rộng phản ứng cho thư viện .NET không?
Fsharp Pete

1
Dưới đây là một số nghiên cứu trên Arrowized FRP và làm thế nào tác động và đột biến có thể được nhúng trong Arrowized FRP mà không vi phạm pháp luật: haskell.cs.yale.edu/wp-content/uploads/2015/10/... (btw nhất thư viện FRP sử dụng Monads hoặc thậm chí Người nộp đơn, vì vậy không đúng khi sử dụng Mũi tên).
Erik Kaplun

17

Cho dù bạn đang sử dụng ngôn ngữ chức năng lai / OO như F # hoặc OCaml, hoặc bằng ngôn ngữ chức năng thuần túy như Haskell, nơi các hiệu ứng phụ được chuyển sang đơn vị IO, chủ yếu là một tấn công việc cần thiết để quản lý GUI giống như một "tác dụng phụ" hơn là một thuật toán đơn thuần.

Điều đó nói rằng, đã có một số nghiên cứu thực sự vững chắc đưa vào GUI chức năng . Thậm chí có một số (hầu hết) các bộ công cụ chức năng như Fudgets hoặc FranTk .


6
"GUIs chức năng" liên kết bị phá vỡ :( cache: webcache.googleusercontent.com/search?q=cache:http://...
Dan Burton


12

Một trong những ý tưởng mở đầu đằng sau Lập trình Phản ứng Chức năng là có chức năng xử lý sự kiện tạo ra phản ứng BÓNG cho các sự kiện VÀ chức năng xử lý sự kiện tiếp theo. Do đó, một hệ thống phát triển được biểu diễn dưới dạng một chuỗi các chức năng xử lý sự kiện.

Đối với tôi, việc học về Yampa đã trở thành một bài thơ quan trọng để có được chức năng sản xuất chức năng đó đúng cách. Có một số giấy tờ tốt đẹp về Yampa. Tôi khuyên bạn nên chơi Yampa Arcade:

http://www.cs.nott.ac.uk/~nhn/Talks/HW2003-YampaArcade.pdf (slide, PDF) http://www.cs.nott.ac.uk/~nhn/Publications/hw2003. pdf (toàn bài, PDF)

Có một trang wiki trên Yampa tại Haskell.org

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

Trang chủ Yampa gốc:

http://www.haskell.org/yampa (không may bị hỏng tại thời điểm này)


1
Liên kết đó bị hỏng trong một thời gian dài. Hãy thử Yampa
CoR

7

Vì câu hỏi này lần đầu tiên được hỏi, lập trình phản ứng chức năng đã được Elm đưa ra một chút chính thống hơn.

Tôi khuyên bạn nên kiểm tra tại http://elm-lang.org , nơi cũng có một số hướng dẫn tương tác thực sự xuất sắc về cách tạo GUI trong trình duyệt đầy đủ chức năng.

Nó cho phép bạn tạo GUI đầy đủ chức năng trong đó mã bạn cần tự cung cấp chỉ bao gồm các hàm thuần túy. Cá nhân tôi thấy việc truy cập dễ dàng hơn nhiều so với các khung GUI Haskell khác nhau.



6

Nói chuyện của Elliot về FRP có thể được tìm thấy ở đây .

Ngoài ra, không thực sự là một câu trả lời mà là một nhận xét và một vài suy nghĩ : bằng cách nào đó, thuật ngữ "GUI chức năng" có vẻ hơi giống một oxymoron (độ tinh khiết và IO trong cùng một thuật ngữ).

Nhưng sự hiểu biết mơ hồ của tôi là lập trình GUI chức năng là về việc khai báo một hàm phụ thuộc thời gian lấy đầu vào người dùng phụ thuộc thời gian (thực) và tạo đầu ra GUI phụ thuộc thời gian.

Nói cách khác, hàm này được định nghĩa giống như một phương trình vi phân khai báo, thay vì bằng thuật toán bắt buộc sử dụng trạng thái có thể thay đổi.

Vì vậy, trong FP thông thường, người ta sử dụng các hàm độc lập với thời gian, trong khi ở FRP, người ta sử dụng các hàm phụ thuộc thời gian làm các khối xây dựng để mô tả chương trình.

Chúng ta hãy suy nghĩ về việc mô phỏng một quả bóng vào mùa xuân mà người dùng có thể tương tác. Vị trí của quả bóng là đầu ra đồ họa (trên màn hình), người dùng đẩy bóng là một phím nhấn (đầu vào).

Việc mô tả chương trình mô phỏng này trong FRP (theo cách hiểu của tôi) được thực hiện bằng một phương trình vi phân duy nhất (khai báo): gia tốc * khối lượng = - độ giãn của lò xo * hằng số lò xo + Lực tác dụng của người dùng.

Dưới đây là video về ELM minh họa quan điểm này.


5

Kể từ năm 2016, có một số khung FRP tương đối trưởng thành hơn cho Haskell như Natri và Reflex (nhưng cũng là Netwire).

Các cuốn sách Manning trên trình phản ứng chức năng trưng bày phiên bản Java của Natri, ví dụ làm việc, và minh họa cách một FRP GUI cư xử cơ sở mã và quy mô so với mệnh lệnh cũng như cách tiếp cận dựa diễn viên.

Ngoài ra còn có một bài báo gần đây về Arrowized FRP và triển vọng kết hợp các tác dụng phụ, IO và đột biến trong việc tuân thủ luật pháp, cài đặt FRP thuần túy: http://haskell.cs.yale.edu/wp-content/uploads/2015/10/ dwc-yale-formatted-dissertation.pdf .

Cũng đáng chú ý là các khung JavaScript như ReactJS và Angular và nhiều khung khác đã hoặc đang chuyển sang sử dụng FRP hoặc cách tiếp cận chức năng khác để đạt được các thành phần GUI có thể mở rộng và có thể kết hợp.


Natri đã không được ủng hộ đối với chuối phản ứng theo github readme của Natri
mac10688


3

Để giải quyết vấn đề này, tôi đã đăng một số suy nghĩ của mình khi sử dụng 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 /

Tôi cũng đang lên kế hoạch thực hiện một video hướng dẫn để hoàn thành loạt bài và cho thấy F # có thể đóng góp như thế nào trong lập trình UX.

Tôi chỉ nói chuyện trong ngữ cảnh của F # ở đây.

-Fahad


2

Tất cả những câu trả lời khác này được xây dựng dựa trên lập trình chức năng, nhưng đưa ra rất nhiều quyết định thiết kế của riêng họ. Một thư viện được xây dựng về cơ bản hoàn toàn ngoài chức năng và các kiểu dữ liệu trừu tượng đơn giản là gloss. Đây là loại cho playchức năng của nó từ nguồn

-- | 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 ()

Như bạn có thể thấy, nó hoạt động hoàn toàn bằng cách cung cấp các hàm thuần túy với các kiểu trừu tượng đơn giản, mà các thư viện khác giúp bạn.


1

Sự đổi mới rõ ràng nhất được nhận thấy bởi những người mới biết đến Haskell là có một sự tách biệt giữa thế giới không tinh khiết liên quan đến việc giao tiếp với thế giới bên ngoài, và thế giới thuần túy của tính toán và thuật toán. Một câu hỏi dành cho người mới bắt đầu thường xuyên là "Làm thế nào tôi có thể thoát khỏi IO, tức là chuyển đổi IO athành a?" Cách để nó là sử dụng các đơn nguyên (hoặc trừu tượng khác) để viết mã thực hiện các hiệu ứng IO và chuỗi. Mã này tập hợp dữ liệu từ thế giới bên ngoài, tạo ra một mô hình của nó, thực hiện một số tính toán, có thể bằng cách sử dụng mã thuần và đưa ra kết quả.

Theo như mô hình trên, tôi không thấy có gì sai trái khủng khiếp với việc thao túng GUI trong IOđơn nguyên. Vấn đề lớn nhất nảy sinh từ phong cách này là các mô-đun không thể kết hợp được nữa, tức là tôi mất hầu hết kiến ​​thức về thứ tự thực hiện toàn cầu của các câu lệnh trong chương trình của mình. Để khôi phục nó, tôi phải áp dụng lý do tương tự như trong mã GUI đồng thời, bắt buộc. Trong khi đó, đối với mã không phải là GUI, thứ tự thực thi là rõ ràng do định nghĩa của toán tử IOđơn nguyên >==(ít nhất là miễn là chỉ có một luồng). Đối với mã thuần túy, hoàn toàn không thành vấn đề, ngoại trừ trong các trường hợp góc để tăng hiệu suất hoặc để tránh các đánh giá dẫn đến .

Sự khác biệt lớn nhất về mặt triết học giữa giao diện điều khiển và IO đồ họa là các chương trình triển khai trước đây thường được viết theo phong cách đồng bộ. Điều này là có thể bởi vì có (để lại các tín hiệu và các bộ mô tả tệp mở khác) chỉ là một nguồn của các sự kiện: luồng byte thường được gọi stdin. GUI vốn dĩ không đồng bộ và phải phản ứng với các sự kiện bàn phím và nhấp chuột.

Một triết lý phổ biến về thực hiện IO không đồng bộ theo cách chức năng được gọi là Lập trình phản ứng chức năng (FRP). Gần đây, nó đã có rất nhiều lực kéo trong các ngôn ngữ không chức năng, không chức năng nhờ các thư viện như ReactiveX và các khung như Elm. Tóm lại, nó giống như xem các thành phần GUI và những thứ khác (như tệp, đồng hồ, báo thức, bàn phím, chuột) dưới dạng nguồn sự kiện, được gọi là "đài quan sát", phát ra các luồng sự kiện. Những sự kiện này được kết hợp sử dụng các nhà khai thác quen thuộc như map, foldl, zip, filter, concat, join, vv, để sản xuất dòng mới. Điều này rất hữu ích vì chính trạng thái chương trình có thể được xem như là scanl . map reactToEvents $ zipN <eventStreams>chương trình, trong đóN bằng với số lượng vật quan sát từng được chương trình xem xét.

Làm việc với các đài quan sát FRP cho phép khôi phục khả năng kết hợp vì các sự kiện trong luồng được sắp xếp kịp thời. Lý do là sự trừu tượng hóa luồng sự kiện cho phép xem tất cả các vật quan sát dưới dạng hộp đen. Cuối cùng, việc kết hợp các luồng sự kiện bằng cách sử dụng các toán tử sẽ trả lại một số thứ tự cục bộ khi thực thi. Điều này buộc tôi phải trung thực hơn nhiều về những bất biến mà chương trình của tôi thực sự dựa vào, tương tự như cách mà tất cả các chức năng trong Haskell phải được minh bạch về mặt tham chiếu: nếu tôi muốn lấy dữ liệu từ một phần khác của chương trình, tôi phải nói rõ quảng cáo khai báo một loại thích hợp cho các chức năng của tôi. (Đơn vị IO, là ngôn ngữ dành riêng cho miền để viết mã không tinh khiết, có hiệu quả phá vỡ điều này)


-22

Lập trình chức năng có thể đã chuyển từ khi tôi còn ở trường đại học, nhưng khi tôi nhớ lại điểm chính của một hệ thống lập trình chức năng là ngăn chặn lập trình viên tạo ra bất kỳ hiệu ứng phụ nào của Drake. Tuy nhiên, người dùng mua phần mềm do các tác dụng phụ được tạo ra, ví dụ như cập nhật giao diện người dùng.


25
Tôi nghĩ rằng bạn đã hiểu sai vấn đề: không phải lập trình chức năng không có tác động bên ngoài đối với thế giới - điều đó sẽ khiến tất cả các chương trình hoàn toàn vô dụng! Thay vào đó, lập trình chức năng cho phép bạn cách ly IO để bạn biết bit nào sử dụng và bit nào không.
Tikhon Jelvis

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.