### Complete wxHaskell Counter Example Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt A comprehensive example integrating Reactive Banana with wxHaskell to create a GUI counter. It demonstrates setting up the GUI, handling button events, managing a counter behavior, and updating a text display using `sink`. ```haskell {-# LANGUAGE RecursiveDo #-} import Graphics.UI.WX hiding (Event) import Reactive.Banana import Reactive.Banana.WX main :: IO () main = start $ do -- Create GUI f <- frame [text := "Counter"] bUp <- button f [text := "Up"] bDown <- button f [text := "Down"] output <- staticText f [text := "0"] set f [layout := margin 10 $ column 5 [ row 5 [widget bUp, widget bDown] , widget output ]] -- Event network let networkDescription :: MomentIO () networkDescription = do eUp <- event0 bUp command eDown <- event0 bDown command bCounter <- accumB 0 $ unions [ (+1) <$ eUp , subtract 1 <$ eDown ] sink output [ text :== show <$> bCounter ] network <- compile networkDescription activate network ``` -------------------------------- ### Behavior Type Examples in Haskell Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Illustrates the `Behavior` type in Reactive-banana, representing time-varying values. Shows how Behaviors are `Applicative` for combining, how to create constant Behaviors, and numerical operations. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Behavior is semantically: Time -> a -- Behaviors are Applicative combineBehaviors :: Behavior Int -> Behavior Int -> Behavior Int combineBehaviors b1 b2 = (+) <$> b1 <*> b2 -- Behaviors can be created from constant values constantBehavior :: Behavior String constantBehavior = pure "Hello, World!" -- Behaviors have Num, Fractional, Floating instances numericBehavior :: Behavior Double -> Behavior Double -> Behavior Double numericBehavior b1 b2 = sqrt (b1 * b1 + b2 * b2) ``` -------------------------------- ### unionWith Event Combinator Examples in Haskell Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Shows how to use the `unionWith` combinator to merge two event streams. Examples include adding values for simultaneous events and keeping the first value. Includes a test case with `interpret`. ```Haskell import Reactive.Banana -- Merge two integer events, adding values on simultaneous occurrence mergeAdding :: Event Int -> Event Int -> Event Int mergeAdding = unionWith (+) -- Merge keeping the first value on collision mergeFirst :: Event a -> Event a -> Event a mergeFirst = unionWith const -- Example with interpret main :: IO () main = do let f e = return $ unionWith (+) (fmap (*2) e) (fmap (*3) e) result <- interpret f [Just 1, Nothing, Just 2] print result -- Output: [Just 5, Nothing, Just 10] (since 2*1+3*1=5, 2*2+3*2=10) ``` -------------------------------- ### Compile and Activate Event Network with compile and activate Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Illustrates the process of compiling an event network using `compile` and then activating it with `activate`. This example shows setting up event sources, accumulating values, and reacting to changes, culminating in firing events to test the network. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Complete example main :: IO () main = do -- Create external event sources (addHandler, fire) <- newAddHandler -- Compile the network network <- compile $ do eInput <- fromAddHandler addHandler bSum <- accumB 0 $ (+) <$> eInput eChanges <- changes bSum reactimate' $ fmap (putStrLn . ("Running sum: " ++) . show) <$> eChanges -- Activate the network activate network -- Fire events mapM_ fire [1, 2, 3, 4, 5] -- Output: Running sum: 1, Running sum: 3, Running sum: 6, ... ``` -------------------------------- ### Haskell: AccumB for Behavior Accumulation Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Illustrates the 'accumB' function for accumulating event values into a Behavior. Examples cover creating a counter behavior, a list accumulator, and integrating behavior changes with UI updates. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Counter behavior counterBehavior :: Event () -> Event () -> Moment (Behavior Int) counterBehavior eUp eDown = accumB 0 $ unions [ (+1) <$ eUp , subtract 1 <$ eDown ] -- List accumulator listAccumulator :: Event a -> Moment (Behavior [a]) listAccumulator e = accumB [] $ (\x xs -> xs ++ [x]) <$> e -- Example with GUI sink networkDescription :: MomentIO () networkDescription = do (eIncrement, _) <- newEvent bCounter <- accumB 0 $ (+1) <$ eIncrement -- The behavior can be used to update UI elements eChanges <- changes bCounter reactimate' $ fmap (putStrLn . ("Counter: " ++) . show) <$> eChanges ``` -------------------------------- ### apply Event Combinator Example in Haskell Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Illustrates the `apply` combinator, which applies a time-varying function (Behavior) to incoming event values. This example shows multiplying event inputs by a behavior-controlled multiplier. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Apply a behavior function to event values networkDescription :: MomentIO () networkDescription = do (eInput, fireInput) <- newEvent -- Create a behavior that holds a multiplier bMultiplier <- stepper 1 never -- Apply the multiplier to incoming events let eResult = apply ((*) <$> bMultiplier) eInput reactimate $ print <$> eResult ``` -------------------------------- ### Event Type Examples in Haskell Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Demonstrates the `Event` type in Reactive-banana, representing discrete occurrences. Shows transformations using `fmap` and merging with `unionWith`. Includes a test case using `interpret` to process a list of potential events. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Event is semantically: [(Time, a)] -- Events can be transformed with Functor example :: Event Int -> Event String example e = fmap show e -- Events can be merged with unionWith mergeEvents :: Event Int -> Event Int -> Event Int mergeEvents e1 e2 = unionWith (+) e1 e2 -- Testing events with interpret main :: IO () main = do result <- interpret (\e -> return $ fmap (*2) e) [Just 1, Nothing, Just 2, Just 3] print result -- Output: [Just 2, Nothing, Just 4, Just 6] ``` -------------------------------- ### Pause and Activate Event Network with pause and activate Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Shows how to control the execution of an event network using `pause` and `activate`. The example demonstrates pausing the network to stop event processing and then reactivating it to resume. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Network with pause capability main :: IO () main = do (addHandler, fire) <- newAddHandler network <- compile $ do e <- fromAddHandler addHandler reactimate $ print <$> e activate network fire 1 -- Prints: 1 pause network fire 2 -- Nothing printed (network paused) activate network fire 3 -- Prints: 3 ``` -------------------------------- ### filterE Event Combinator Examples in Haskell Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Demonstrates the `filterE` combinator for selectively keeping events that satisfy a given predicate. Examples include filtering for positive and even numbers, with a test case using `interpret`. ```Haskell import Reactive.Banana -- Filter to only positive numbers positiveOnly :: Event Int -> Event Int positiveOnly = filterE (> 0) -- Filter to only even numbers evenOnly :: Event Int -> Event Int evenOnly = filterE even -- Testing with interpret main :: IO () main = do result <- interpret (\e -> return $ filterE even e) [Just 1, Just 2, Just 3, Just 4] print result -- Output: [Nothing, Just 2, Nothing, Just 4] ``` -------------------------------- ### Create Updatable Behavior with newBehavior Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Demonstrates how to create a behavior that can be updated programmatically using `newBehavior`. This function returns a behavior and an update handler. The example shows updating the behavior's value and reacting to changes. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Create updateable behavior networkDescription :: MomentIO () networkDescription = do (bValue, updateValue) <- newBehavior "initial" (eTrigger, _) <- newEvent -- Sample behavior when triggered reactimate $ (\() -> print =<< return bValue) <$ eTrigger -- Update can be called from IO liftIO $ updateValue "updated" ``` -------------------------------- ### Haskell: Unions for Merging Event Streams Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Explains the 'unions' function for merging multiple event streams. It shows how to combine different update events to control a behavior and provides a vending machine example demonstrating its use in managing state transitions. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Combine multiple update events multipleUpdates :: Event () -> Event () -> Event Int -> Moment (Behavior Int) multipleUpdates eIncr eDecr eSet = accumB 0 $ unions [ (+1) <$ eIncr , subtract 1 <$ eDecr , const <$> eSet ] -- Vending machine example vendingMachine :: Event () -> Moment (Event (), Behavior Int) vendingMachine eCoin = do let price = 50 rec bAmount <- accumB price $ unions [ subtract 10 <$ eCoin , const price <$ eSold ] let eSold = whenE ((<= 0) <$> bAmount) eCoin return (eSold, bAmount) ``` -------------------------------- ### Connect Behaviors to Widget Properties with sink Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Illustrates using the `sink` function to connect Reactive Banana behaviors to wxHaskell widget properties. This automatically updates the widget whenever the behavior's value changes, as shown in the example with a counter updating a static text label. ```haskell import Graphics.UI.WX hiding (Event, Behavior) import Reactive.Banana import Reactive.Banana.WX -- Update widget properties from behaviors networkDescription :: StaticText () networkDescription = do eClick <- event0 button command bCounter <- accumB 0 $ (+1) <$ eClick -- Automatically update label text when counter changes sink output [ text :== show <$> bCounter ] ``` -------------------------------- ### Haskell: MapAccum for Stateful Transformations Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Introduces 'mapAccum', an efficient function for combining stateful accumulation of events and behaviors. Examples include generating unique IDs and performing stateful transformations on event data with output. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Generate unique IDs uniqueIdGenerator :: Event a -> Moment (Event Int, Behavior Int) uniqueIdGenerator e = mapAccum 0 $ (\acc -> (acc, acc + 1)) <$ e -- Stateful transformation with output statefulTransform :: Event Int -> Moment (Event String, Behavior Int) statefulTransform e = mapAccum 0 $ (\x acc -> let newAcc = acc + x in ("Sum is now: " ++ show newAcc, newAcc) ) <$> e ``` -------------------------------- ### Haskell: AccumE for Event Accumulation Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Details the 'accumE' function for accumulating event values using a strict left scan. Examples include counting events and calculating a running sum, as well as a more complex counter with up/down events. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Count events countEvents :: Event a -> Moment (Event Int) countEvents e = accumE 0 $ (+1) <$ e -- Running sum runningSum :: Event Int -> Moment (Event Int) runningSum e = accumE 0 $ (+) <$> e -- Example: Counter with up/down events networkDescription :: MomentIO () networkDescription = do (eUp, fireUp) <- newEvent (eDown, fireDown) <- newEvent eCount <- accumE 0 $ unions [ (+1) <$ eUp , subtract 1 <$ eDown ] reactimate $ print <$> eCount ``` -------------------------------- ### filterJust Event Combinator in Haskell Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Shows the `filterJust` combinator, which filters out `Nothing` values from an event stream of `Maybe` types, keeping only `Just` values. Includes an example of parsing strings to integers. ```Haskell import Reactive.Banana -- Parse integer events, keeping only successful parses parseInts :: Event String -> Event Int parseInts = filterJust . fmap readMaybe where readMaybe s = case reads s of [(x, "")] -> Just x _ -> Nothing -- Testing with interpret main :: IO () main = do result <- interpret (\e -> return $ filterJust e) [Just (Just 1), Just Nothing, Just (Just 2)] print result -- Output: [Just 1, Nothing, Just 2] ``` -------------------------------- ### Constructing a Val Expression in Haskell Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Defines a `val` combinator that constructs a `Val` expression and binds it to a fresh name within a monadic context. It uses `fresh` to get a new name and `bind` to associate the `Val` expression with it. ```haskell val :: Int -> M Name val i = do name <- fresh bind name $ Val i pure name ``` -------------------------------- ### Implement unionWith for Event in reactive-banana Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/Multiple-Simultaneous-Events-(Issue- Defines the `unionWith` function for `Event` types, which combines two events using a provided function. It utilizes `foldr1` and `collect` to process the union of the input events. The example demonstrates its usage with lists of integers. ```haskell unionWith :: (a -> a -> a) -> Event a -> Event a -> Event a unionWith f e1 e2 = foldr1 f <$> collect (e1 `union` e2) ``` -------------------------------- ### Pure implementation with ST monad Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/TODO.md Demonstrates how to make a push-driven implementation pure by utilizing the ST monad instead of the IO monad for the Vault data type. This is suggested for applications like MIDI generation. ```haskell The push-driven implementation can be made pure by putting the `Vault` data type into the `ST` monad instead of the `IO` monad. This might be useful for MIDI, i.e. using one and the same code for both real-time MIDI generation and writing it to files. ``` -------------------------------- ### Embedding Arithmetic Expressions with Host Language `let` Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Illustrates how a simple arithmetic expression language can be embedded into a host language (like Haskell) using smart constructors and the host language's `let` binding. It highlights the potential for expression duplication when `let` is used naively. ```haskell y :: Exp y = let x = val 1 + val 2 in (x * x) ``` -------------------------------- ### Convert Widgets to Layouts Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/wx-Control-Overview Demonstrates the conversion of various widgets into a layout structure. This allows for programmatic arrangement and management of UI elements. ```haskell widget staticText widget input1 widget cmb widget styledTxt ``` -------------------------------- ### Create wxHaskell Events with event0 and event1 Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Demonstrates creating Reactive Banana events from wxHaskell widget events using `event0` for events without parameters (like button clicks) and `event1` for events with parameters (like mouse events). ```haskell import Graphics.UI.WX hiding (Event) import Reactive.Banana import Reactive.Banana.WX -- Create events from button clicks networkDescription :: Button () networkDescription = do eClick <- event0 button command reactimate $ putStrLn "Button clicked!" <$ eClick -- Create events with parameters mouseNetwork :: Panel () mouseNetwork = do eMouse <- event1 panel mouse let eLeftClick = filterJust $ leftDown <$> eMouse reactimate $ print <$> eLeftClick ``` -------------------------------- ### Using Embedded `Let` for Expression Sharing Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Demonstrates how to rewrite the previously duplicated expression using the extended `Exp` data type with `Let` and `Var` constructors. This explicitly represents sharing within the embedded DSL. ```haskell y' = Let "x" (val 1 + val 2) (Var "x" * Var "x") ``` -------------------------------- ### Create Combo Box Widget Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/wx-Control-Overview Implements a combo box widget, providing a dropdown list of predefined items. It can be initialized with a list of strings. ```haskell cmb ← comboBox f [items := ["item1","item2"]] ``` -------------------------------- ### Create wxHaskell Behavior with behavior Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Explains how to create a Reactive Banana behavior by polling a wxHaskell widget's attribute using the `behavior` function. This allows the widget's state to be sampled periodically or in response to other events. ```haskell import Graphics.UI.WX hiding (Event, Behavior) import Reactive.Banana import Reactive.Banana.WX -- Poll widget state as behavior networkDescription :: TextCtrl () networkDescription = do bText <- behavior textCtrl text (eTrigger, _) <- newEvent -- Sample text at each trigger let eTextSample = bText <@ eTrigger reactimate $ putStrLn <$> eTextSample ``` -------------------------------- ### Haskell: Stepper for Creating Step-Function Behaviors Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Explains the 'stepper' function, which creates a Behavior from an initial value and a stream of update events. It demonstrates how to create a behavior that changes its value based on incoming events and how to observe these changes. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Create a behavior that steps through values networkDescription :: MomentIO () networkDescription = do (eUpdate, fireUpdate) <- newEvent -- Behavior starts at 0, updates when events occur bValue <- stepper 0 eUpdate -- Sample the behavior eChanges <- changes bValue reactimate' $ fmap print <$> eChanges -- Testing with interpret main :: IO () main = do result <- interpret (\e -> do b <- stepper "initial" e return $ b <@ e ) [Just "first", Nothing, Just "second"] print result -- Output: [Just "initial", Nothing, Just "first"] ``` -------------------------------- ### Haskell: Infix Operators for Applying Behaviors to Events Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Demonstrates the use of infix operators <@>, <@, and @> for applying behavior values to events or tagging events with behavior values. These operators simplify common patterns in event-driven programming. ```haskell import Reactive.Banana import Reactive.Banana.Frameworks -- <@> is infix apply applyExample :: Behavior (a -> b) -> Event a -> Event b applyExample bf ex = bf <@> ex -- <@ tags events with the current behavior value tagWithBehavior :: Behavior b -> Event a -> Event b tagWithBehavior b e = b <@ e -- @> is flipped <@, useful with ApplicativeDo tagFlipped :: Event a -> Behavior b -> Event b tagFlipped e b = e @> b -- Example: Tag button clicks with current counter value networkDescription :: MomentIO () networkDescription = do (eClick, _) <- newEvent bCounter <- accumB 0 $ (+1) <$ eClick -- Get counter value at each click let eCounterAtClick = bCounter <@ eClick reactimate $ print <$> eCounterAtClick ``` -------------------------------- ### Create Styled Text Control Widget Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/wx-Control-Overview Initializes a styled text control, a multi-line textbox with advanced features like highlighting and code completion, suitable for IDE-like applications. ```haskell styledTxt ← styledTextCtrl f [] ``` -------------------------------- ### Create Label Layout Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/wx-Control-Overview Generates an immutable label for display purposes within the layout. It takes a string as an argument to set the label's text. ```haskell label "myLabeltext" ``` -------------------------------- ### Create Text Entry Widget Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/wx-Control-Overview Creates a text entry widget, also known as TextCtrl, which allows for user input. The content can be programmatically changed. ```haskell input1 ← entry f [] ``` -------------------------------- ### Arithmetic Expression Data Type with Variables and Let Bindings Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Extends the `Exp` data type to include explicit support for variables (`Var`) and let bindings (`Let`). This allows for direct representation of sharing within the embedded language itself, addressing the duplication issue. ```haskell data Name = String data Exp = ... | Var Name | Let Name Exp Exp -- let name = e1 in e2 ``` -------------------------------- ### Monadic Structure for Variable Binding and Lookup Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Presents a conceptual monadic structure `M` designed to manage variable bindings and lookups. This monad would store associations between names and expressions, facilitating shared evaluation and providing operations for managing this state. ```haskell fresh :: M Name bind :: Name -> Exp -> M () lookup :: Name -> M (Maybe Exp) ``` -------------------------------- ### Create Static Text Widget Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/wx-Control-Overview Defines a static text widget that displays read-only text. This text can be modified programmatically but not by user interaction. ```haskell staticText ← staticText f [] ``` -------------------------------- ### Create Events from External Handlers with fromAddHandler (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The fromAddHandler function integrates external event sources into the Reactive Banana framework. It takes an AddHandler (a function to register callbacks) and converts it into an Event, allowing external systems to trigger events within the reactive network. This is crucial for bridging the gap between imperative and reactive code. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks import Control.Event.Handler -- Create event from external callback networkDescription :: AddHandler Int -> MomentIO () networkDescription addHandler = do eExternal <- fromAddHandler addHandler reactimate $ print <$> eExternal -- Full example with handler setup main :: IO () main = do (addHandler, fireEvent) <- newAddHandler network <- compile $ do e <- fromAddHandler addHandler reactimate $ putStrLn . ("Received: ") . show <$> e activate network -- Fire events fireEvent 1 fireEvent 2 fireEvent 3 ``` -------------------------------- ### Representing Events as a List of Time-Tagged Values Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md This snippet shows a simple, though problematic, way to represent a sequence of discrete events with their timestamps. It uses a lazy list to allow future events to be added, but suffers from potential time leaks if not managed carefully. ```haskell type Events a = [(Time, a)] ``` -------------------------------- ### Dynamically Switch Behaviors with switchB (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The switchB function enables dynamic switching between different behavior sources. It takes an initial behavior and an event that emits new behaviors, allowing the system to change its underlying state representation. This is valuable for adapting to changing data sources or configurations. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Switch between different value sources switchValueSource :: Behavior a -> Event (Behavior a) -> Moment (Behavior a) switchValueSource initial eSwitchTo = switchB initial eSwitchTo -- Example: Switch between data sources networkDescription :: MomentIO () networkDescription = do (eSwitch, _) <- newEvent let bSource1 = pure "Source 1" bSource2 = pure "Source 2" bCurrent <- switchB bSource1 $ bSource2 <$ eSwitch eChanges <- changes bCurrent reactimate' $ fmap print <$> eChanges ``` -------------------------------- ### Shared and Unshared Expression Construction in Haskell Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Demonstrates two ways to construct expressions using monadic combinators. `y` uses the host language's `let` for immediate binding, while `y'` uses monadic assignment `<-` for delayed binding, illustrating the difference between immediate and shared variable binding. ```haskell y :: M Name y = do let x = val 1 + val 2 x * x y' :: M Name y' = do x' <- val 1 + val 2 let x = var x' x * x ``` -------------------------------- ### Dynamically Switch Event Streams with switchE (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The switchE function allows dynamic switching between different event sources. It takes an initial event stream and an event that emits new event streams, effectively changing the source of events over time. This is useful for scenarios where the event generation logic needs to adapt based on external triggers. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Switch to new event source when signal occurs dynamicEventSource :: Event a -> Event (Event a) -> Moment (Event a) dynamicEventSource initial eSwitchTo = switchE initial eSwitchTo -- Example: Mode switching networkDescription :: MomentIO () networkDescription = do (eInput, _) <- newEvent (eMode, _) <- newEvent let eDouble = fmap (*2) eInput eTriple = fmap (*3) eInput -- Switch between doubling and tripling based on mode events eResult <- switchE eDouble $ eTriple <$ eMode reactimate $ print <$> eResult ``` -------------------------------- ### Observe Moment Values at Event Occurrences with observeE (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The observeE function allows executing moment computations at the time events occur. It takes an event that emits moment computations and returns an event that yields the results of those computations. This is useful for sampling behavior values or performing side effects within the reactive network. ```Haskell import Reactive.Banana -- Execute moment computations when events occur observeAtEvents :: Event (Moment a) -> Event a observeAtEvents = observeE -- Sample a behavior at specific events sampleAtEvent :: Behavior a -> Event b -> Event a sampleAtEvent b e = observeE $ valueB b <$ e ``` -------------------------------- ### Creating a Union of Pulses in the Build Monad Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md This function demonstrates how to combine two 'Pulse' values within the 'Build' monad, which represents changes to a mutable graph. This is a mid-level operation in the reactive-banana library's implementation. ```haskell union :: Pluse a -> Pulse a -> Build (Pulse a) ``` -------------------------------- ### Schedule and delay events Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/TODO.md Schedules a sequence of events, delaying them but cutting them off if a new event arrives. This is considered very useful when used recursively. ```haskell -- delay a sequence of events, but cut them off when a new one comes -- very useful when used recursively schedule :: Event (a,Duration) -> Event a ``` -------------------------------- ### Monoid Instance for Event (a -> a) in reactive-banana Source: https://github.com/heinrichapfelmus/reactive-banana/wiki/Multiple-Simultaneous-Events-(Issue- Removes the general `Monoid` instance for `Event` and introduces a specific `Monoid` instance for `Event (a -> a)`. The `mempty` is `never`, and `mappend` is implemented using `unionWith` with function composition. ```haskell instance Monoid (Event (a -> a)) where mempty = never mappend = unionWith (flip (.)) ``` -------------------------------- ### Create New Events with newEvent (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The newEvent function creates a pair: an Event and a function to fire that event. This allows for the creation of internal events within a reactive network, enabling feedback loops and complex event generation. The fire function can be used within reactimate or other parts of the network description. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Create event/handler pair networkDescription :: MomentIO () networkDescription = do (eInput, fireInput) <- newEvent -- Use fireInput in reactimate to create feedback let eTransformed = fmap (*2) eInput reactimate $ (\x -> do print x when (x < 100) $ fireInput (x + 1) ) <$> eTransformed ``` -------------------------------- ### Wrap an action in a caching mechanism using cache in Haskell Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md The `cache` function takes an arbitrary monadic action `m a` and wraps it in the `Cached` monad. This allows the action to be executed only once, with subsequent calls returning the cached result, similar to combining `unsafePerformIO` and `lookup`. ```haskell cache :: m a -> Cached m a ``` -------------------------------- ### Arithmetic Expression Data Type Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Defines a simple data type `Exp` for representing arithmetic expressions, including integer values, addition, and multiplication. This serves as a basis for demonstrating expression evaluation and embedding. ```haskell data Exp = Val Int -- plain `Int` | Add Exp Exp -- addition | Mul Exp Exp -- multiplication ``` -------------------------------- ### Time behavior in reactive systems Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/TODO.md Represents the current time within a reactive system, likely as a behavior that updates over time. This is crucial for enabling continuous time behaviors. ```haskell time :: Behavior Time ``` -------------------------------- ### Observable Sharing Addition Combinator in Haskell Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Implements an addition combinator `(+)` with observable sharing. It uses `unsafePerformIO` to conditionally generate a fresh name. If the name is already bound, it reuses the existing name; otherwise, it binds a new `Add` expression. This ensures shared sub-expressions are evaluated only once. ```haskell -- with observable sharing (+) :: M Name -> M Name -> M Name (+) = \a b -> unsafePerformIO $ do name <- fresh pure $ do mexp <- lookup name case mexp of Nothing -> do x <- a y <- b bind name $ Add (Var x) (Var y) Just _ -> pure $ Var name ``` -------------------------------- ### Execute IO Actions on Event Occurrence with reactimate (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The reactimate function allows executing arbitrary IO actions whenever an event occurs. It takes an Event and an IO action that consumes the event's value, enabling side effects like printing, file writing, or network communication within the reactive system. Multiple reactimate calls can observe the same event. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Execute IO on event occurrence networkDescription :: MomentIO () networkDescription = do (eInput, fireInput) <- newEvent -- Print each event reactimate $ print <$> eInput -- Multiple reactimates can observe the same event reactimate $ putStrLn . ("Logged: ") . show <$> eInput -- Example with side effects networkWithSideEffects :: MomentIO () networkWithSideEffects = do (eSave, _) <- newEvent reactimate $ (\content -> do writeFile "output.txt" content putStrLn "File saved!" ) <$> eSave ``` -------------------------------- ### Addition Combinator for Monadic Expressions in Haskell Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Implements an addition combinator `(+)` for monadic expressions. It executes two argument 'macros' (monadic actions), retrieves their resulting names, generates a fresh name for the addition, and binds an `Add` expression using the retrieved names. ```haskell (+) :: M Name -> M Name -> M Name (+) a b = do x <- a y <- b name <- fresh bind name $ Add (Var x) (Var y) pure name ``` -------------------------------- ### Define a one-time event with duration Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/TODO.md Defines an event that occurs once at a specific duration relative to the UNIX epoch. This primitive is noted as not very useful without dynamic event switching. ```haskell type Duration = -- time difference in UNIX epoch -- event that happens once (not very useful without dynamic event switching) once :: a -> Duration -> Event era a ``` -------------------------------- ### Observe Behavior Changes with changes (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The changes function adapts a behavior to produce an event stream that fires whenever the behavior's value changes. This is useful for reacting to state updates in a granular way. It typically works in conjunction with reactimate' to process these change events. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Observe behavior changes networkDescription :: MomentIO () networkDescription = do (eUpdate, _) <- newEvent bValue <- stepper "initial" eUpdate -- Get events when behavior changes eChanges <- changes bValue -- Use reactimate' with Future values from changes reactimate' $ fmap (putStrLn . ("New value: ") ++) <$> eChanges ``` -------------------------------- ### never Event Combinator in Haskell Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt Demonstrates the `never` combinator in Reactive-banana, which creates an event that never occurs. It's shown as a base case for switching event streams. ```Haskell import Reactive.Banana -- An event that never fires emptyEvent :: Event a emptyEvent = never -- Useful as a base case for switching example :: Event Int -> Moment (Event Int) example e = switchE never (const never <$> e) ``` -------------------------------- ### Define Behavior and Events types using Cached monad in Haskell Source: https://github.com/heinrichapfelmus/reactive-banana/blob/master/reactive-banana/doc/design/design.md Defines the `Behavior` and `Events` types as `Cached` actions within the `Moment` monad. This caching ensures that the underlying computations, such as building `Pulse` or `Latch` values, are executed only once. ```haskell type Behavior a = Cached Moment (Latch a, Pulse ()) ``` ```haskell type Events a = Cached Moment (Pulse a) ``` -------------------------------- ### Keep Only the First Event Occurrence with once (Haskell) Source: https://context7.com/heinrichapfelmus/reactive-banana/llms.txt The once function filters an event stream, ensuring that only the first occurrence of an event is propagated. Subsequent events are discarded. This is commonly used for initialization logic or actions that should only happen once. ```Haskell import Reactive.Banana import Reactive.Banana.Frameworks -- Get only the first event firstEventOnly :: Event a -> Moment (Event a) firstEventOnly = once -- Example: Initialize on first click networkDescription :: MomentIO () networkDescription = do (eClick, _) <- newEvent eFirstClick <- once eClick reactimate $ putStrLn "First click received!" <$ eFirstClick ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.