2012-12-17 25 views
19

Dường như với tôi rằng có một kết nối mạnh mẽ giữa hai ý tưởng. Đoán của tôi là FRP có thể được thực hiện theo Iteratees nếu có cách nào để biểu diễn các đồ thị tùy ý với các Iterate. Nhưng afaik họ chỉ hỗ trợ cấu trúc giống như chuỗi.Kết nối giữa Iteratees và FRP là gì?

Ai đó có thể làm sáng tỏ điều này?

Trả lời

13

Đó là một cách khác. Có một kết nối mạnh mẽ giữa AFRP và xử lý luồng. Trong thực tế AFRP một hình thức xử lý dòng, và bạn có thể sử dụng thành ngữ để thực hiện một cái gì đó rất giống với ống:

data Pipe m a b = 
    Pipe { 
     cleanup :: m(), 
     feed :: [a] -> m (Maybe [b], Pipe m a b) 
    } 

Đó là một phần mở rộng của loại dây như được tìm thấy trong Netwire. Nó nhận được phần đầu vào tiếp theo và trả về Không có gì khi nó ngừng sản xuất. Sử dụng này đọc một tập tin sẽ có các loại sau đây:

readFile :: (MonadIO m) => FilePath -> Pipe m a ByteString 

Pipe là một gia đình functors applicative, vì vậy để áp dụng một chức năng đơn giản để các yếu tố dòng bạn chỉ có thể sử dụng fmap:

fmap (B.map toUpper) . readFile 

Để thuận tiện cho bạn, đó cũng là một gia đình giáo sư.

Tính năng thú vị nhất là đây là gia đình của những người thay thế. Điều đó cho phép bạn định tuyến luồng xung quanh và cho phép nhiều bộ xử lý luồng "thử" trước khi từ bỏ. Điều này có thể được mở rộng đến một thư viện phân tích cú pháp chính thức, thậm chí có thể sử dụng một số thông tin tĩnh cho các mục đích tối ưu hóa.

+0

Ah, tôi chuẩn bị đăng nội dung tương tự, nhưng tôi sẽ trì hoãn chuyên môn của một người thực sự đã viết thư viện AFRP. :] –

+0

Dường như sử dụng (A) FRP tôi sẽ không bị giới hạn trong cấu trúc biểu đồ tuần hoàn, điều này có đúng không? – fho

+3

Tôi không rõ câu trả lời của bạn là gì nếu không thể thực hiện bất kỳ khía cạnh nào của AFRP về mặt hoặc luồng gần đây có thư viện/ống dẫn? – Davorak

13

Bạn có thể triển khai một dạng giới hạn FRP bằng bộ xử lý luồng. Ví dụ, sử dụng thư viện pipes, bạn có thể xác định nguồn gốc của sự kiện:

mouseCoordinates :: (Proxy p) =>() -> Producer p MouseCoord IO r 

... và bạn tương tự có thể định nghĩa một handler đồ họa mà có tọa độ chuột và cập nhật một con trỏ trên vải:

coordHandler :: (Proxy p) =>() -> Consumer p MouseCoord IO r 

Sau đó, bạn sẽ treo lên các sự kiện chuột để xử lý sử dụng thành phần:

>>> runProxy $ mouseCoordinates >-> coordHandler 

Và nó sẽ chỉ chạy theo cách mà bạn mong đợi.

Như bạn đã nói, điều này hoạt động tốt cho một chuỗi các giai đoạn, nhưng còn về các cấu trúc liên kết tùy ý hơn thì sao? Vâng, nó chỉ ra rằng kể từ khi Proxy loại trung tâm của pipes là một biến áp monad, bạn có thể mô hình hóa bất kỳ topo tùy ý chỉ bằng cách làm tổ máy biến áp monad proxy trên đầu trang của mình. Ví dụ: dưới đây là cách bạn sẽ nén hai luồng đầu vào:

zipD 
:: (Monad m, Proxy p1, Proxy p2, Proxy p3) 
=>() -> Consumer p1 a (Consumer p2 b (Producer p3 (a, b) m)) r 
zipD() = runIdentityP $ hoist (runIdentityP . hoist runIdentityP) $ forever $ do 
    a <- request()    -- Request from the outer Consumer 
    b <- lift $ request()  -- Request from the inner consumer 
    lift $ lift $ respond (a, b) -- Respond to the Producer 

Hoạt động này giống như chức năng đã kết thúc. Bạn áp dụng nó một phần cho mỗi đầu vào tuần tự và sau đó bạn có thể chạy nó khi nó được áp dụng đầy đủ.

-- 1st application 
p1 = runProxyK $ zipD <-< fromListS [1..] 

-- 2nd application 
p2 = runProxyK $ p2  <-< fromListS [4..6] 

-- 3rd application 
p3 = runProxy $ printD <-< p3 

Nó chỉ chạy theo cách mà bạn mong đợi:

>>> p3 
(1, 4) 
(2, 5) 
(3, 6) 

lừa này khái quát cho bất kỳ topo.Bạn có thể tìm thấy nhiều thông tin chi tiết hơn về điều này trong Control.Proxy.Tutorial trong phần "Chi nhánh, nén và hợp nhất". Đặc biệt, bạn nên kiểm tra bộ phối hợp fork mà nó sử dụng làm ví dụ, cho phép bạn tách luồng thành hai đầu ra.

+0

Tôi khá chắc chắn điều này đúng với tất cả các thư viện lặp đi lặp lại. Oleg đã sử dụng nó một thời gian trước đây. Tôi không chắc tại sao không ai có thể nhớ rằng có thể; kỹ thuật này rất hữu ích. –

+0

@JohnL Đó là lý do tại sao bạn phải thuyết giảng nó! Không phải ai cũng biết Oleg đã làm gì. –

+0

Ngay cả những người biết Oleg thường không hiểu điều đó. Đáng buồn là tôi thường xuyên ở trong nhóm này, ít nhất là lúc đầu ... –

Các vấn đề liên quan