Comments (14)
Similar to changes
. Which might be suitable depending on your use case.
Also, usually achievable with a Dynamic
, which is essentially a tuple of an Event
and a Behavior
. The event has the new value, while the behaviour will hold the previous value at a given instant.
from reactive-banana.
Unfortunately I don't think such a combinator is actually permitted by the model. Recall that a Behavior a
is morally a Time -> a
function, and Event a
is [(Time, a)]
. I don't see a way to accurately transform Eq a => Time -> a
to [(Time, (a, a))]
. We'd need to answer this question before anything else. I think as @luke-clifton says, what you might want instead is Dynamic
.
from reactive-banana.
Hmm, Time is discrete, right? So in the model you loop over every time value until it changes. If f(t) ≠ f(next t)
, then the event contains (t, (f(t), f(next t))
.
from reactive-banana.
No, time is continuous. https://hackage.haskell.org/package/reactive-banana-1.3.1.0/docs/Reactive-Banana-Model.html states:
The FRP model used in this library is actually a model with continuous time. However, it can be shown that this model is observationally equivalent to a particular model with (seemingly) discrete time steps, which is implemented here
But I don't quite know what this means 🤔
from reactive-banana.
Like, the actual implementation of the model represents behaviors as lists. And as long as behaviors are piecewise constant, detecting updates is still semantically meaningful (it's the set of discontinuities).
from reactive-banana.
It is desirable that behaviours appear continuous. Breaking that breaks the model.
from reactive-banana.
Hmm, what about a function that detects isolated discontinuities?
discontinuities :: Eq a => Behavior a -> Event (a, a)
With the current implementation, it would be the same as updates
since every definable behavior is piecewise continuous. But if a continuous behavior is ever added (like a clock) it wouldn't trigger discontinuities
because like the name says, it is only triggered by discontinuous changes. In particular, it is triggered with (left limit, right limit)
when they both exist and are different.
Another name could be jumps
because it detects "jumps" in the function.
from reactive-banana.
The thing is, Reactive Banana only samples behaviors on events anyway. So, you already have that event lying around, you may as well just re-use it (which is what a Dynamic
gives you). The model explicitly doesn't know anything about the discontinuities of raw behaviors.
Take, for example, the fromPoll
function. You might build a behavior like fromPoll getCurrentTime
. getCurrentTime
has a discontinuity every second, but Reactive Banana is only going to poll it when some other event occurs in the network. Without the events, reactive banana has no idea that the above behavior has a discontinuity every second, and it would not know to generate an event.
If we just rely on internal events for sampling, and want our discontinuities
function anyway, well, now the events generated depend on the sampling rate, i.e. on other events occurring in the network. If the network was busy, we would see a jittery event every second, but if the network was quiet, we would see no events. This would be a very surprising behavior (heh).
from reactive-banana.
(err, pretend that the getCurrentTime
function, is accurate to the second, for my wording above, it's obviously even weirded with higher resolution clocks)
from reactive-banana.
Oh, I forgot about fromPoll
. It's kind of cursed to think of there being a time function from a continuous domain to the pure (non-io) integer values, but that is how fromPoll timeInSecondsIO
gets modeled. I have no idea how you'd implement discontinuities
then. You can't sample an IO action continuously.
The only thing I can think of is you somehow knew the maximum sampling frequency of the RAM, maybe that would suffice (what IO action could update faster than that)? idk
from reactive-banana.
(for pure values I know infinite search is possible (see this) but I think fromPoll
does kill the idea)
Unless maybe you change fromPoll
's requirements, requiring it's argument's samples to be continuous in time? fromChanges
could still be used for behaviors from IO that are discontinuous.
from reactive-banana.
So, even with pure behaviours things get tricky, and you would need to begin relying on numerical methods to find discontinuities. These methods would also rely on the sampling behaviour, and could miss short discontinuities.
Once you start down this road, you are no longer in interactive FRP, but more like an integration system based on FRP. I did have a prototype of such a library for modelling dynamical systems before, and the only way to trigger events was from zero crossings of the behaviour. It would also adjust the sampling frequency intelligently and perform a bisection search, jumping backwards in time as required to get within a desired accuracy of the root. While it's an interesting way of creating dynamical systems, one must always be on the lookout for tricky sample rate dependent gotchas.
The beauty of continuous time FRP is that you just do not have to worry about any of that ever.
Also, when sampling from the real world, it's kinda hard to guarantee anything. Using fromPoll
to read an analogue signal (continuous!) from the output of a push button is a perfectly valid use case if you don't actually need an edge trigger, you might even debounce and round it and convert it to a bool inside the FRP network. But if you change your mind about the edge triggered thing, you might get upset to find that discontinuities
only works on some behaviours.
from reactive-banana.
So, even with pure behaviours things get tricky, and you would need to begin relying on numerical methods to find discontinuities. These methods would also rely on the sampling behaviour, and could miss short discontinuities.
...
The beauty of continuous time FRP is that you just do not have to worry about any of that ever.
This post talks about exhaustive search, so you shouldn't be able to miss any discontinues, even the short ones. There is no sampling rate. It works very differently than a float
or double
based solution, since those are discrete types. (tl;dr, you have a function that constructs a potential solution that is correct if any solution exists. It works corecursively: it finds a potential solution that starts with zero, and if that solution fails, it returns the potential solution starting with one instead. Using this function, you can check if there is a solution by searching just one value, the potential solution from the function.)
That being said, it appears that both updates
and discontinuities
are incompatible with fromPoll
, so I'm going to close this issue. I have a much better understanding of the problems with these type of combinators though (I was kind of wondering why it wasn't already in the library), thanks!
from reactive-banana.
But if you're curious about the details for how it would work for FRP without IO, here is the basic idea. I'll base it on this post, which is what the infinite search monad post was based on.
Time would be (Integer, Cantor)
, where the second part represents the binary expansion after the integer part (so (3, [\n -> cycle [Zero, One] !! n))
represents 3 and a third). A behavior is a function with this as the domain.
Then you get something like
updates :: Eq a => (Integer, Cantor) -> ((Integer, Cantor) -> a) -> [((Integer, Cantor), a)]
updates start behavior = case search of
Just c -> [((fst start, c), behavior (fst start, c))] : updates (fst start, c) behavior
Nothing -> updates (fst start + 1, const Zero)
where
start_val = behavior start
next = search (\c -> if behavior (fst start, c) == start_val //search is defined in the blog post
then false
else c > snd start //`>` can be a given a definition that is total in this context since we know c ≠ snd start in this branch)
Note that search
is much more efficient than brute force (which would take infinite time, but even for the finite analogues it's way faster) because it exploits laziness. It's faster if you use a more efficient find (such as find_viii
).
from reactive-banana.
Related Issues (20)
- `reactive-banana` can't be compiled on GHC 9.2 HOT 2
- I created a Matrix channel HOT 8
- An interesting `Applicative`-ish way of combining `Event`s HOT 4
- Add `MonadMoment` instances for all monad transformers in `transformers` HOT 1
- Release 1.3.0.0 HOT 3
- Join Stackage HOT 4
- `Behavior` constantly re-evaluating when caching is expected HOT 4
- Unexpected memory growth HOT 6
- Event handler not seeing early events. HOT 12
- `Behavior`s can hold onto more memory than they need to HOT 2
- Memory leak with dynamic behavior switching HOT 16
- Gloss GUI events not responding HOT 5
- Call `unregister` for garbage collected events made by `AddHandler`. HOT 9
- Discrepancy in model and implementation HOT 15
- Optimize representation of Latch HOT 1
- Not compatible with these-1.2 (disallowed) HOT 2
- Simultaneous events can have undefined behavior within execute HOT 2
- source-code formatter? HOT 2
- Accept deepseq-1.5 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reactive-banana.