खोज…


पुस्तकालय में बाहरी घटनाओं का इंजेक्शन लगाना

यह उदाहरण किसी भी ठोस GUI टूलकिट से बंधा नहीं है, उदाहरण के लिए प्रतिक्रियाशील-केला-डब्ल्यूएक्स करता है। इसके बजाय यह दिखाता है कि एफआरपी मशीनरी में मनमानी IO क्रियाओं को कैसे इंजेक्ट किया जाए।

Control.Event.Handler मॉड्यूल एक addHandler फ़ंक्शन प्रदान करता है जो AddHandler a और a -> IO () मानों की एक जोड़ी बनाता है। पूर्व का उपयोग प्रतिक्रियाशील-केला द्वारा स्वयं किसी Event a मान प्राप्त करने के लिए किया जाता है, जबकि बाद वाला एक सादा फ़ंक्शन है जिसका उपयोग संबंधित ईवेंट को ट्रिगर करने के लिए किया जाता है।

import Data.Char (toUpper)

import Control.Event.Handler
import Reactive.Banana

main = do
    (inputHandler, inputFire) <- newAddHandler

हमारे मामले में हैंडलर का a पैरामीटर टाइप String , लेकिन कोड जो कंपाइलर का पता लगाता है जो बाद में लिखा जाएगा।

अब हम EventNetwork को परिभाषित करते हैं जो हमारे FRP- संचालित प्रणाली का वर्णन करता है। यह compile फ़ंक्शन का उपयोग करके किया जाता है:

main = do
    (inputHandler, inputFire) <- newAddHandler
    compile $ do
        inputEvent <- fromAddHandler inputHandler

fromAddHandler फ़ंक्शन AddHandler a को एक Event a में AddHandler a मान में बदल देता Event a , जो अगले उदाहरण में कवर किया गया है।

अंत में, हम अपना "इवेंट लूप" लॉन्च करते हैं, जो उपयोगकर्ता इनपुट पर घटनाओं को आग लगाएगा:

main = do
    (inputHandler, inputFire) <- newAddHandler
    compile $ do
        ...
    forever $ do
        input <- getLine
        inputFire input

घटना प्रकार

प्रतिक्रियाशील-केले में Event प्रकार समय में कुछ घटनाओं की एक धारा का प्रतिनिधित्व करता है। एक Event इस अर्थ में एक एनालॉग आवेग संकेत के समान है कि यह समय में निरंतर नहीं है। नतीजतन, Event का एक उदाहरण है Functor केवल typeclass। आप दो Event एक साथ जोड़ नहीं सकते क्योंकि वे अलग-अलग समय पर आग लगा सकते हैं। आप Event के [वर्तमान] मान के साथ कुछ कर सकते हैं और कुछ IO क्रिया के साथ उस पर प्रतिक्रिया कर सकते हैं।

Event मान पर रूपांतरणों को fmap का उपयोग करके किया जाता है:

main = do
    (inputHandler, inputFire) <- newAddHandler
    compile $ do
        inputEvent <- fromAddHandler inputHandler
        -- turn all characters in the signal to upper case
        let inputEvent' = fmap (map toUpper) inputEvent

किसी Event पर प्रतिक्रिया उसी तरह से की जाती है। पहले आप इसे टाइप fmap a -> IO () की कार्रवाई के साथ और फिर इसे reactimate फ़ंक्शन में पास करें:

main = do
    (inputHandler, inputFire) <- newAddHandler
    compile $ do
        inputEvent <- fromAddHandler inputHandler
        -- turn all characters in the signal to upper case
        let inputEvent' = fmap (map toUpper) inputEvent
        let inputEventReaction = fmap putStrLn inputEvent' -- this has type `Event (IO ())
        reactimate inputEventReaction

अब जब भी inputFire "something" कहा जाता है, "SOMETHING" inputFire "something" मुद्रित किया जाएगा।

व्यवहार प्रकार

महाद्वीपीय संकेतों का प्रतिनिधित्व करने के लिए, प्रतिक्रियाशील-केला Behavior a प्रकार का Behavior a । विपरीत Event , एक Behavior एक है Applicative , आप गठबंधन एन की सुविधा देता है जो Behavior एक n-ary शुद्ध समारोह का उपयोग कर s (का उपयोग कर <$> और <*> )।

एक प्राप्त करने के लिए Behavior a से Event a है accumE समारोह:

main = do
    (inputHandler, inputFire) <- newAddHandler
    compile $ do
        ...
        inputBehavior <- accumE "" $ fmap (\oldValue newValue -> newValue) inputEvent

accumE Behavior के प्रारंभिक मूल्य और एक Event लेता है, जिसमें एक फ़ंक्शन होता है जो इसे नए मूल्य पर सेट करेगा।

Event एस के साथ, आप वर्तमान Behavior मान के साथ काम करने के लिए fmap का उपयोग कर सकते हैं, लेकिन आप उन्हें (<*>) भी जोड़ सकते हैं।

main = do
    (inputHandler, inputFire) <- newAddHandler
    compile $ do
        ...
        inputBehavior  <- accumE "" $ fmap (\oldValue newValue -> newValue) inputEvent
        inputBehavior' <- accumE "" $ fmap (\oldValue newValue -> newValue) inputEvent
        let constantTrueBehavior = (==) <$> inputBehavior <*> inputBehavior'

Behavior परिवर्तन पर प्रतिक्रिया करने के लिए एक changes कार्य है:

main = do
    (inputHandler, inputFire) <- newAddHandler
    compile $ do
        ...
        inputBehavior  <- accumE "" $ fmap (\oldValue newValue -> newValue) inputEvent
        inputBehavior' <- accumE "" $ fmap (\oldValue newValue -> newValue) inputEvent
        let constantTrueBehavior = (==) <$> inputBehavior <*> inputBehavior'
        inputChanged <- changes inputBehavior

केवल बात यह है कि ध्यान दिया जाना चाहिए कि है changes लौट Event (Future a) के बजाय Event a । इस वजह से, reactimate' के बजाय प्रयोग किया जाना चाहिए reactimate । इसके पीछे का तर्क प्रलेखन से प्राप्त किया जा सकता है।

EventNetworks को सक्रिय करना

EventNetwork compile द्वारा लौटाए जाने से पहले पुन: सक्रिय होने वाली घटनाओं का प्रभाव होना चाहिए।

main = do
    (inputHandler, inputFire) <- newAddHandler

    eventNetwork <- compile $ do
        inputEvent <- fromAddHandler inputHandler
        let inputEventReaction = fmap putStrLn inputEvent
        reactimate inputEventReaction

    inputFire "This will NOT be printed to the console!"
    actuate eventNetwork
    inputFire "This WILL be printed to the console!"


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow