2013-06-23 24 views
5

ıOlaylar bir IO işleviyle nasıl dönüştürülür?

e1 :: Event t A 
f :: A -> IO B 

Ben e1 tarafından tetiklenir hangi

e2 :: Event t B 

oluşturmak istediğiniz var ve kimin değerleri olay gerçekleştiği bir zamanda e1 değerine f yürüterek belirlenir diyelim .

Dinamik olay geçişi ve işleyicileri kullanarak bunu yapmak için iki potansiyel yol görüyorum, ancak her ikisi de çok basit bir şey için çok karmaşık görünüyorlar.

Bunu yapmanın doğru yolu nedir?

+0

'unsafePerformIO' bir seçenektir? – Ankur

+1

@Ankur: hayır, kesinlikle bir «uygun yol» değil. –

cevap

2

f işlevinin bir yan etkisi olduğundan, bu aslında yapılması gereken bir şey değildir. Ana neden, birden fazla eşzamanlı olay olduğunda yan etkilerin sırasının iyi tanımlanmamasıdır. Daha genel olarak, olaylarda IO eylemleriyle uğraşmak için iyi bir semantik tasarlayamadım. Sonuç olarak, reaktif muz bu durum için saf bir birleştirici sağlamaz.

Yine de bunu yapmak istiyorsanız, yan etkilerin sırasını da belirleyen daha ayrıntılı bir mekanizma kullanmalısınız. Örneğin, reactimate kullanıp Ancak bir bağdaştırıcının

mapIO :: Frameworks t => (a -> IO b) -> Event t a -> Moment t (Event t b) 
mapIO f e1 = do 
    (e2, fire2) <- liftIO newAddHandler 
    reactimate $ (\x -> f x >>= fire2) <$> e1 
    fromAddHandler e2 

yazma, artık giriş olayı e1 ile eşzamanlı olan bu sonuç olay e2 olarak beklenmeyen sonuçlar verebilir unutmayın edebilirsiniz. Örneğin, davranışlar değişmiş olabilir ve diğer yan etkiler gerçekleştirilmiş olabilir.

+1

FRP'nin bütün amacının IO ile uğraşmak olduğu ve IO eylemlerinin "birinci sınıf" olmadığı göz önüne alındığında, bu biraz şaşırtıcıdır. Özellikle, eşzamanlı olayların siparişi var - o zaman neden ilgili efektler için aynı siparişi kullanmıyorsunuz? Bunun, kurşun geçirmez olmadığını anlıyorum - örn. bir IO eylemi diğer olayları tetikleyebilir veya olayları "eş zamanlı" olarak kabul etmek için çok zaman harcar ... Ama bunun için sorumluluk alabilirim; Yani, herhangi bir olay işleyicisini çağırmamaya söz veriyorum ve eylem amacım için "anlık" olacak. Hala imkansız mı? Niye ya? –

+1

Eh, eşzamanlı olaylar her olayda bir sıralamaya sahip olabilir, ancak küresel bir sıralama yoktur. Iki olay "sendika ex ey" ve "eski" ve "ey" eşzamanlı oluşumlar var send send ey. Bir program her iki bileşimi de aynı anda kullanabilir, ancak her biri için aynı anda gerçekleşen olayların sırası farklı olacaktır. Daha genel olarak, olaylarda IO eylemleri sipariş etmek için iyi bir semantik bulamadım, bu nedenle reaktif-muz onları desteklemez. (Bu noktayı vurgulamak için cevabımı güncelledim.) –

+2

Genel olarak FRP ile ilgili olarak, umarım bunun bir hayal kırıklığı olarak gelmediğini umarız, ancak odak noktası, olaylarla ve zamanla değişen değerlerle hesaplanırken, IO'da değil. Bununla birlikte, genellikle sınırda IO ile arabirim kurmak zorundasınız ve burada birçok tepki var: "tepki ver" veya burada sunulan "mapIO" birleştiricisi veya "Reactive.Banana.Frameworks" deki "mapIO" birleştiricisi.AddPandler modülü, FRP dünyasına geçmeden önce olayları değiştirmek için kullanılabilir. –

1
numaralı telefondan f işlevini çağırabilir miyim (anladığım kadarıyla olay ağındaki IO'yu işlemek için "uygun yol")? Oradan, etkinlik ağına yeni bir olay olan Event t B'u ateşleyin. Yoksa "işleyicileri kullanarak" ne demek istediniz?
+0

Evet, "işleyicileri kullanarak" demek istediğim buydu. –

İlgili konular