5

Conal Elliott talks about Streams and Comonads here: http://conal.net/blog/posts/sequences-streams-and-segments

However, he doesn't mention Behavior directly. So.. is Behavior a Comonad, and if so - what does that mean practically?

For starters - I suppose Behavior can provide the extend and extract functions. The only way I see that working is if it samples the value at a specific moment in time.

Is that what Comonad would mean for Behavior? That it allows one to "fork and freeze" a Behavior?

In other words - if we have a Behavior that has these values over time: A,B,C,D,... we could extend it at the time where it's B, and get a new Behavior which contains B indefinitely (which is useful - since we could then lift or map it etc.)

davidkomer
  • 3,020
  • 2
  • 23
  • 58
  • 4
    This doesn't sound like a pure function if the result depends upon the time of the call – Bergi Aug 23 '18 at 09:31
  • Very good point! :D – davidkomer Aug 23 '18 at 10:03
  • 1
    It is pure in the sense that the time is a pure value. While `now` is in the `IO` monad, a particular time in the past or future is a pure value. – Bob Dalgleish Aug 23 '18 at 15:41
  • @BobDalgleish But we don't pass in the time as an argument – Bergi Aug 24 '18 at 07:47
  • @Bergi Have a read of section 2 of [_Push-Pull FRP_](http://conal.net/papers/push-pull-frp/push-pull-frp.pdf). `Behaviour a` denotes `Time -> a`, in the sense that a `Behaviour` can be sampled at any time and sampling a `Behaviour` has no side-effects. `Time -> a` is a model, not the actual implementation, but it tells you a lot about how `Behaviour`s compose. The fact that the `Time` is handled implicitly by the framework doesn't change the model, much as using a parser combinator library to handle leftovers and backtracking doesn't change the `String -> [(a, String)]` model. – Benjamin Hodgson Aug 24 '18 at 10:26
  • @BenjaminHodgson I know Push-Pull FRP, but I don't see how you can write a function `extract :: (Time -> a) -> a` without an impure (or useless?) construction of a Time value – Bergi Aug 24 '18 at 13:56
  • @Bergi -∞ (ie the behaviour's initial value) would seem like a natural choice. No idea whether that can be efficiently implemented – Benjamin Hodgson Aug 24 '18 at 13:59
  • @BenjaminHodgson yeah, that might work (with `duplicate` mapping the behaviour to a behaviour of itself with all past values forgotten). – Bergi Aug 24 '18 at 14:11
  • Not in the standard semantics, but there was some exploration of *relative-time* FRP for a bit, in which `Behavior` is a comonad (& `extract` samples at time 0). – luqui Aug 25 '18 at 03:32

1 Answers1

3

Behavior a is isomorphic to (Time -> a). The definitions Conal gives in the section of that post "Adding continuity" match those in the comonad package.

It is not obvious to me how to make time a Monoid. Several Monoid instances are possible, but are any useful? Conal's post on future values suggests that the Max is a useful Monoid for working with time.

This works out that extract @Behavior gives the value at the earliest possible time, and duplicate @Behavior gives the value at the later of the two times. I can see both of those being useful. Perhaps there are other useful Monoids also?

bergey
  • 3,041
  • 11
  • 17