Haskell Language
रिएक्टिव-केला
खोज…
पुस्तकालय में बाहरी घटनाओं का इंजेक्शन लगाना
यह उदाहरण किसी भी ठोस 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!"