2011-12-23 7 views
16

मान लीजिए कि मेरे पास एक ईवेंट ट्रिगर है जिसे मैं निकालकर दो चीजें करना चाहता हूं। सबसे पहले, मैं इसे व्यवहार के मान को अपडेट करना चाहता हूं। दूसरा, यदि अन्य स्थितियों को पूरा किया जाता है, तो मैं इसे व्यवहार के मूल्य के साथ send_off पर आग लगाना चाहता हूं। कोड रूप में व्यक्त किया, मैंप्रतिक्रियाशील-केला: एक व्यवहार के सबसे अद्यतित मूल्य वाले फायरिंग ईवेंट

trigger :: Event b 
trigger = ... 

updateFromTrigger :: b -> (a -> a) 
updateFromTrigger = ... 

conditionFromTrigger :: b -> Bool 
conditionFromTrigger = ... 

behavior :: Behavior a 
behavior = accumB initial_value (updateFromTrigger <$> trigger) 

send_off :: Event a 
send_off = ?????? (filterE conditionFromTrigger trigger) 

है तो फिर सवाल यह है कि लगता है: क्या मैं में डाल दिया है ?????? ताकि send_offव्यवहार का सबसे अद्यतित मूल्य भेजता है, जिसके द्वारा मेरा मतलब है कि से अद्यतन को शामिल करने वाला मान ट्रिगर है जो इसे अभी लागू किया गया था।

दुर्भाग्यवश, यदि मैं सही ढंग से समझता हूं, तो व्यवहार का अर्थशास्त्र ऐसा है कि अद्यतन मूल्य तुरंत मेरे लिए उपलब्ध नहीं है, इसलिए मेरा एकमात्र विकल्प काम को डुप्लिकेट करने और व्यवहार के अद्यतन मूल्य को फिर से लागू करने के लिए अनिवार्य रूप से है। इसे किसी अन्य घटना में तुरंत उपयोग कर सकते हैं, यानी ??????

send_off = 
    flip updateFromTrigger 
    <$> 
    behavior 
    <@> 
    filterE conditionFromTrigger trigger 

अब की तरह कुछ के साथ, वहाँ एक भावना है, जिसमें मैं व्यवहार में अद्यतन जानकारी मेरे पास उपलब्ध तुरंत एक व्यवहार के बजाय एक असतत का उपयोग करके कर सकते हैं, लेकिन वास्तव में यह सिर्फ के बराबर है मुझे एक ऐसा कार्यक्रम दे रहा है जो अद्यतन मूल्य के साथ मेरे मूल कार्यक्रम के साथ एक साथ निकाल दिया गया है, और जब तक कि मुझे कुछ प्रतिक्रियाशील-केला नहीं मिला है, तब तक मुझे एक घटना को आग लगाने का कोई तरीका नहीं मिलता है जब दो अन्य घटनाओं ने एक साथ निकाल दिया है; यानी, यह घटनाओं के संघों को प्रदान करता है लेकिन चौराहे नहीं।

तो मेरे पास दो प्रश्न हैं। सबसे पहले, क्या इस स्थिति की मेरी समझ सही है, और विशेष रूप से मैं निष्कर्ष में सही हूं कि मेरा समाधान उपरोक्त काम करने का एकमात्र तरीका है? दूसरा, जिज्ञासा से पूरी तरह से, डेवलपर्स द्वारा घटनाओं के चौराहे से निपटने के तरीके पर कोई विचार या योजना रही है?

उत्तर

6

उत्कृष्ट सवाल!

दुर्भाग्यवश, मुझे लगता है कि मौलिक समस्या है जिसमें कोई आसान समाधान नहीं है। समस्या निम्न है: आप सबसे हालिया संचित मूल्य चाहते हैं, लेकिन trigger में एक साथ घटनाओं (जो अभी भी आदेश दिया गया है) हो सकता है। फिर,

कौन सा एक साथ संचयी अद्यतन सबसे हालिया होने जा रहा है?

मुद्दा यह है कि अद्यतन अन्य घटना धाराओं के संबंध में घटना धारा वे संबंध रखते हैं में आदेश दिया जाता है, लेकिन नहीं है। यहां इस्तेमाल किए गए एफआरपी अर्थशास्त्र अब नहीं जानते कि behavior पर एक साथ अद्यतन कौन सा एक साथ send_off ईवेंट से मेल खाता है। विशेष रूप से, इससे पता चलता है कि send_off के लिए आपके प्रस्तावित कार्यान्वयन की संभावना गलत है; यह काम नहीं करता है जब trigger में एक साथ घटनाएं होती हैं क्योंकि व्यवहार को कई बार अपडेट किया जा सकता है, लेकिन आप केवल एक बार अपडेट को फिर से समझ रहे हैं।

इस के साथ

मन में, मैं समस्या के कई दृष्टिकोण के बारे में सोच सकते हैं:

  1. उपयोग mapAccum नए-नए अपडेट संचायक से प्रत्येक का मान ट्रिगर घटना पर टिप्पणी करने के लिए।

    (trigger', behavior) = mapAccum initial_value $ f <$> trigger 
        where 
        f x acc = (x, updateFromTrigger acc) 
    
    send_off = fmap snd . filterE (conditionFromTrigger . fst) $ trigger' 
    

    मुझे लगता है कि इस समाधान प्रतिरूपकता के मामले में थोड़ा कमी है, लेकिन उपरोक्त चर्चा के आलोक में, यह शायद से बचने के लिए मुश्किल है।

  2. Discrete के संदर्भ में सब कुछ याद करें।

    मेरे पास कोई ठोस सुझाव नहीं है, लेकिन हो सकता है कि आपका send_off ईवेंट उचित ईवेंट की तुलना में किसी मान के अपडेट की तरह महसूस करता हो। उस स्थिति में, Discrete के संदर्भ में सबकुछ डालने के लायक हो सकते हैं, जिनके Applicative उदाहरण एक साथ होने पर "सही चीज़" होता है।

    इसी तरह की भावना में, मैं अक्सर changes . accumD का उपयोग accumE के बजाय करता हूं क्योंकि यह अधिक प्राकृतिक लगता है।

  3. प्रतिक्रियाशील-केला (> 0.4.3) के अगले संस्करण की संभावना कार्यों

    collect :: Event a -> Event [a] 
    spread :: Event [a] -> Event a 
    

    शामिल होंगे कि वस्तु के बारे में जैसे सोचना, resp। एक साथ घटनाओं को प्रतिबिंबित करें। मुझे उन्हें Discrete वैसे भी अनुकूलित करने की आवश्यकता है, लेकिन वे वर्तमान प्रश्नों की तरह सामान के लिए भी उपयोगी हैं।

    विशेष रूप से, वे तुम्हें thusly घटनाओं के चौराहे को परिभाषित करने की अनुमति होगी:

    intersect :: Event a -> Event b -> Event (a,b) 
    intersect e1 e2 
         = spread . fmap f . collect 
         $ (Left <$> e1) `union` (Right <$> e2) 
        where 
        f xs = zipWith (\(Left x) (Right y) -> (x,y)) left right 
         where (left, right) = span isLeft xs 
    

    हालांकि, उपरोक्त चर्चा के आलोक में, इस समारोह कम उपयोगी से आप चाहें तो इसे होने की हो सकती है। विशेष रूप से, यह अद्वितीय नहीं है, कई प्रकार हैं।

+0

किसी भी भावना का जब हम अपडेट की उम्मीद कर सकते हैं? :-) –

+0

@ ग्रेगरी क्रॉसवाइट: आप अच्छे प्रश्न पूछते रहते हैं। ;-) मैंने नए आंतरिक के लिए एक सुंदर डिजाइन सोचा है, लेकिन इसे लागू करने में कुछ समय लगेगा। –

संबंधित मुद्दे