2011-12-25 23 views
14

Tôi hiện đang cố gắng tìm hiểu FRP thông qua Heinrich Apfelmus 'reactive-banana, có vẻ như là một thư viện tài liệu và đơn giản khá tốt, so với các thư viện khác mà tôi đã xem xét.reactive-banana: Cách tạo AddHandler?

Tuy nhiên, tôi không thể quấn đầu quanh loại AddHandler. Giả sử tôi muốn sử dụng GLFW để nhận các nhấp chuột vào nút chuột để tôi có một cái gì đó như eMouseButton :: Event(). Nhìn vào các ví dụ, có vẻ như tôi bằng cách nào đó phải sử dụng fromAddHandler, nhưng tôi không có ý tưởng làm thế nào để lắp ráp đối số AddHandler đó. Tôi nghĩ rằng tôi sẽ phải sử dụng newAddHandler bằng cách nào đó, nhưng làm thế nào?

Tôi đoán ví dụ về cách kết nối reactive-banana với một thứ khác ngoài wx sẽ giúp ích rất nhiều.

Trả lời

14

newAddHandler được sử dụng như thế này:

do (addHandler, fire) <- newAddHandler 
    ... 

addHandler là AddHandler để vượt qua để reactive-banana, và fire là một chức năng của loại a -> IO() (nơi một là loại sự kiện của bạn) mà kích hoạt sự kiện.

Ví dụ, bạn sẽ có khả năng cài đặt fire như gọi lại để sự kiện chuột nút GLFW, như vậy:

registerMouseButton :: IO (Event MouseButton) 
registerMouseButton = do 
    (addHandler, fire) <- newAddHandler 
    setMouseButtonCallback $ \button _ -> fire button 
    fromAddHandler addHandler 

(Tôi không có kinh nghiệm với GLFW, vì vậy tôi không chắc chắn về thứ hai Lập luận để gọi lại setMouseButtonCallback 's là - nếu điều quan trọng là, bạn sẽ cần phải sửa đổi điều này thực hiện một cách thích hợp)

một AddHandler chỉ là một chức năng mà phải mất một callback - a -> IO() - và đăng ký nó cho sự kiện trong câu hỏi. nó sau đó lợi nhuận (từ bên trong IO) một hành động IO() sử dụng để xoá đăng ký xử lý này, làm cho complete definition of AddHandler đọc như sau:

type AddHandler a = (a -> IO()) -> IO (IO()) 

Vì vậy, nơi nào newAddHandler vào được không? Đơn giản: newAddHandler duy trì danh sách các trình xử lý cho một sự kiện và kích hoạt chúng khi fire x được thực thi.

Bạn không cần newAddHandler nếu như GTK + và nhiều bộ công cụ phổ biến khác, bộ công cụ của bạn đã có cơ sở để đăng ký và hủy đăng ký nhiều trình xử lý sự kiện; nếu có, bạn nên viết bản thực hiện của riêng mình là AddHandler. Nhưng nếu tất cả nó hỗ trợ là một cuộc gọi lại duy nhất, bạn nên sử dụng newAddHandler.

Lưu ý rằng bạn không bao giờ cần tự phơi bày AddHandler s cho chính mã FRP đang sử dụng; chúng chỉ là keo nội bộ được sử dụng để tạo ra Event s từ các đầu vào bên ngoài.

+0

Cuối cùng nó được nhấp! Cảm ơn bạn. – bzn

+0

Rất tiếc - lần cuối cùng tôi sử dụng chuối phản ứng với bộ công cụ GUI, tôi đã viết một liên kết ngắn (~ 30 dòng) với GTK +, có chức năng này; Tôi đã không thực sự được sử dụng wxWidgets, nhưng giả định rằng nó đã làm quá, bởi vì thực hiện một 'AddHandler' cho GTK + là rất tự nhiên :) Sau khi điều tra thêm, nó không; Tôi đã sửa chữa câu trả lời của mình. – ehird

+0

@ bzn: Về cơ bản, wxWidgets không cung cấp cách để hủy đăng ký lại các trình xử lý sự kiện cụ thể, đó là lý do tại sao tôi phải sử dụng tiện ích 'newAddHandler'. –