2012-07-31 70 views
7

我是新來的一般反應性香蕉和玻璃鋼,所以道歉,如果我失去了明顯的東西。執行zipE ::事件t a - >事件t b - >事件t(a,b)

對於my project(a GDB/MI前端)我對GUI和前端邏輯模塊都使用反應香蕉(版本0.6.0.0)。前者效果很好,但對於後者我顯然需要額外的組合器。其中之一是zipE :: Event t a -> Event t b -> Event t (a, b)。不幸的是,我能想出是在使用changes,而不是通用的事件類型NetworkDescription單子的解決方案:

zipE :: Event t Int -> Event t String -> NetworkDescription t (Event t (Int, String)) 
zipE ea eb = changes $ (,) <$> stepper 0 ea <*> stepper "" eb 

當然,我並不滿足於此。因此我想問如何在不使用changes(不鼓勵用於非GUI目的)的情況下實現通用的zipE函數。

其他嘗試失敗,例如

zipE :: Num a => Event t a -> Event t b -> Event t (a,b) 
zipE ea eb = apply (stepper (0,) ((,) <$> ea)) eb 

導致元組的第一元件由一個被移動 - 我想由於stepper引入的「輕微的延遲」。但是我沒有看到如果沒有stepper(或者accumB就是這個問題),如何從一個事件中獲得行爲,我看不到如何將一個函數應用到沒有行爲的事件。總的來說,我不知道如何在泛型類型的情況下爲步進器提供初始值。

+2

'ea'和'eb'不會同時開火。 (如果你知道他們會同時發射,因爲它們都來自同一個基礎事件,那麼重新處理這個基礎事件可能是最好的。)當一個人發生火災而另一個人發火時,你想要發生什麼? T' – dave4420 2012-07-31 14:44:06

+0

戴夫,你是對的。我需要爲我的活動網絡設計不同的設計: - /謝謝您指出這一點。 – copton 2012-07-31 15:04:53

+2

我確實需要一個不同的事件網絡。最初,我想壓縮兩個事件,將元組提供給'f ::(a,b) - > IO()'。我現在所擁有的是'f :: a - > b - > IO()'和'reachable $(步進器0 aE)<@> bE'。 – copton 2012-07-31 16:39:15

回答

13

您在定義zipE時遇到困難,因爲它沒有語義意義。如果考慮語義定義

Event a == [(Time, a)] 
Event b == [(Time, b)] 

沒有拉上他們,因爲一般每個事件將是在不同的時間以自然的方式。

可以使用總和而不是產品壓縮它們。

zipE :: Event a -> Event b -> Event (Either a b) 
zipE aE bE = (Left <$> aE) `mappend` (Right <$> bE) 

如果你真的需要在同一時間有兩個ab,合適的解決方案是創建一個Behavior是日積月累的一個或另一個,或與上述合併Either流。

編輯:在合併流(未測試)上累積的一種方式的示例。其他實現也是可能的。這不會使兩個事件同時發生,而是讓您將當前狀態與過去狀態組合在一起,因此您始終可以使用LeftRight值中的最新值。

currentAandB :: a -> b -> Event a -> Event b -> Event (a,b) 
currentAandB a0 b0 aE bE = accumE (a0,b0) (mergefn <$> zipE aE bE) 
    where 
     mergefn (Left a) (_,b) = (a,b) 
     mergefn (Right b) (a,_) = (a,b) 

仍然需要爲兩個Event流提供初始值。這樣想:如果你只有Event a的事件,那麼元組的第二部分應該具有什麼價值?

+0

約翰,謝謝你幫助我。我想知道更多關於您提到的適當答案。請你詳細說明一個或另一個事件如何累積使得兩個事件同時發生?對不起,如果這很明顯。我只是沒有看到它。 – copton 2012-07-31 15:22:30

+1

準確地說,我會建議。 – Conal 2012-07-31 15:40:39

+0

@copton:我已經發布了一個這樣做的方法的例子。至於初始值,如果您考慮問題的初始狀態,您可能會找到明智的答案。或者,您可以使用'Maybe','Data.Traversable.sequenceA'和'filterJust'的組合,在您接收到'a'和'b'後僅產生輸出。 – 2012-07-31 16:09:56

相關問題