[Haskell-beginners] FRP

Ertugrul Söylemez es at ertes.de
Wed Oct 3 16:12:45 CEST 2012


Heinrich Apfelmus <apfelmus at quantentunnel.de> wrote:

> So, netwire is essentially based on the abstraction
>
>      type Stoplight red green = Behavior' (Either red green)
>
> of time-varying values that can either be a "normal" value of type
> green , or an "exceptional" ("inhibiting") value of type red . (I have
> dropped the input dependence, so that arrow composition becomes normal
> function application.)
>
> Here, Behavior' denotes a type of continues time-varying values, with
> the small twist that it can "detect some flanks", namely when the
> value jumps from Right to Left . In this way, the flank can be
> interpreted as an Event in the reactive-banana sense.

This is not really how it works.  Inhibition causes the rest of the wire
to inhibit, in other words:

    _ . empty = empty


> The applicative instance is the composition of the applicative
> instances for Behavior' and Either
>
>      instance Monoid red => Applicative (Stoplight red) where
>          pure x  = pure (Right x)
>          f <*> x = (<$)> <$> f <*> x
>
> if we assume that  Either  has the following applicative instance
>
>      instance Monoid red => Applicative (Either red) where
>          pure = Right
>          (Right x) <*> (Right y) = Right (x y)
>          (Left  x) <*> (Right y) = Left  x
>          (Right x) <*> (Left  y) = Left  y
>          (Left  x) <*> (Left  y) = Left  (x <*> y)

In particular the above means that with (<*>) when the function wire
inhibits, the application itself inhibits:

    empty <*> _ = empty

The Monoid constraint is on the Alternative class instead, where
selection happens.  The reason why it has to be a monoid is for the
Alternative laws to hold.


> What I particularly like about this approach is the following: I like
> to think of Behavior as continuous functions, not necessarily because
> they are really continuous, but because this means that the semantics
> of Behavior is independent of any "update frequency", which is key
> point in simplifying code with FRP. Unfortunately, this means that we
> cannot "detect flanks", because a continuously changing Behavior
> simply does not change in discrete steps.
>
> The Stoplight type solves this problem by introducing an explicit
> "this is a flank" value, i.e. by using the fact that the only way an
> Either type can change is in discrete steps. Due to parametricity, I
> can't put this information into the general Behavior type, but the
> special case Behavior (Either red green)  can make use of this.

Netwire doesn't do everything to hide the discrete nature of stepping,
but this isn't really a conceptual choice, but rather the simple fact
that I provide predefined wires that expose this (for example in
Control.Wire.Prefab.Accum).  If you use only time-continuous wires, then
the perception is the same as in a continuous model, probably even more
so as handling events becomes simple algebra instead of explicit
switching:

    "yes" . holdFor 1 (periodically 2) <|> "no"

The reason is that Netwire is developed with flexibility in mind.  In
fact the original motivation was to enable development of reactive
networking applications, where time or continuity isn't much of a
concern.  I wanted to be able to express such systems declaratively
without giving up the ability to reason easily about how it will behave
at runtime.

There is an experimental web framework based on Netwire 1 called
Webwire, and I'm planning to revive it, because FRP makes developing web
applications (server side!) really convenient, especially when you have
to handle forms or other interactive things.


> On the other hand, while the combination of Behaviors and Events
> allows for some slick switching combinators, I'm not entirely sure
> whether the mixture of two unrelated concepts (continuous functions vs
> singular occurrences) is too much of a conceptual burden.

The wire concept is at least equivalent to the classic events/behaviors
split, because you can translate both behaviors and events to wires.
You will find that most event signal functions from Yampa are also
present in Netwire, except that they are potentially inhibiting wires
instead of event signals.


Greets,
Ertugrul

-- 
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20121003/2c92cfb5/attachment.pgp>


More information about the Beginners mailing list