[Haskell-cafe] A question about causality in FRP

David Barbour dmbarbour at gmail.com
Fri Oct 14 11:48:34 CEST 2011


On Fri, Oct 14, 2011 at 1:31 AM, Ertugrul Soeylemez <es at ertes.de> wrote:

> David Barbour <dmbarbour at gmail.com> wrote:
>
> > If you want first-class behaviors or behavior transformers, those will
> > need a different abstraction than 'nested' behaviors. Nested != First
> > Class.  You'd have special functions to lift a first-class behavior as
> > an argument (e.g. add a phantom type to prohibit non-causal
> > observation), and to lower it into the main system for sampling
> > (e.g. ArrowApply).
>
> The usual model for arrowized FRP is based on this type:
>
>    newtype Auto a b = Auto (a -> (b, Auto a b))
>
> I would be very interested in how you would write an ArrowApply instance
> for such a type.  So far my conclusion is:  It's impossible.
>

Interesting claim. The implementation is obvious enough:
  runAuto (Auto f) = f
  app = Auto $ \ (f,x) -> let (x',f') = runAuto f x in (x',app)

Which arrow laws does this violate? Or is your concern that a fresh arrow
supplied to `app` at each instant obviously cannot accumulate state?

Yampa AFRP model chooses to model products using the `Either` type - i.e.
indicating that either element can be updated independently.  Using this,
one could accumulate state in the captured arrow, though there'd be a funky
reset whenever the arrow is updated.

Getting back on topic, protecting causality requires that we prevent
sampling of a first-class Auto element. One way to do this is to use a
Rank2Type similar to the ST monad:

  newtype Auto era a b = Auto { unAuto :: a -> (b, Auto era a b) }
  runAuto :: (forall era . Auto era a b) -> [a] -> [b]

This would prevent developers from `running` an Auto of a known era, except
by protected mechanisms such as ArrowApply.  Simulations would need to be
era-independent.

The reactive model I'm developing, Reactive Demand Programming, is actually
anti-causal: behavior at any given instant may depend only upon its present
and future inputs (anticipation), but never the past. State is treated as an
external service, part of an abstract machine, orchestration of registers or
a database. I think this setup works better than FRP, e.g. for controlling
space-leaks, supporting smooth transitions and upgrades of dynamic behavior,
modeling the app as a whole as dynamic, and orthogonal persistence.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20111014/862c27cb/attachment.htm>


More information about the Haskell-Cafe mailing list