[Haskell-cafe] AFRP is not (necessarily) imperative
David Barbour
dmbarbour at gmail.com
Mon Dec 12 21:59:24 CET 2011
This would make a good blog article...
2011/12/12 Ertugrul Söylemez <es at ertes.de>
> Hello fellows,
>
> after a few discussions on IRC and via private mail I feel obligated to
> point out that arrows and in particular AFRP do not force you to use an
> imperative style in any way. You can use a style very similar to SHE's
> idiom brackets. I will demonstrate this using the Netwire library. The
> following code has a very imperative feel to it and also looks quite
> ugly:
>
> myWire =
> proc _ -> do
> fps <- avgFpsInt 1000 100 -< ()
> t <- time -< ()
> let x = 3 + t
> y <- integral 0 -< t
> returnA -< printf "%8.2f %8.2f %8.2f" fps x y
>
> Let's improve this code. The magic lies in identifying behaviors from
> classic FRP. The arrow variables from the above code can be seen as the
> behaviors, but that's not very useful for getting rid of the imperative
> style. A better way to look at it is that every wire that ignores its
> input (i.e. has a fully polymorphic input type) is a behavior, so let's
> find them.
>
> First of all it is impossible to write a proper Num instance for wires.
> The underlying problem is the same as for writing a Num instance for
> functions. However, the Wire type forms a vector space, and the next
> release of Netwire will include the corresponding instances (see the
> vector-space package by Conal Elliot). With them we can write:
>
> x = constant 3 ^+^ time
>
> The x wire is our first behavior. Passing x to a generic wire is
> simply regular arrow composition, giving you behaviors as functions of
> other behaviors, hence:
>
> y = integral 0 <<< x
>
> Also fps is just a simple behavior:
>
> fps = avgFpsInt 1000 100
>
> To get to the final output there are multiple ways. Perhaps the nicest
> way is to exploit the Applicative instance, giving you:
>
> myWire =
> liftA3 (printf "%8.2f %8.2f %8.2f") fps x y
>
> where
> fps = avgFpsInt 1000 100
> x = constant 3 ^+^ time
> y = integral 0 <<< x
>
> Looks much more declarative, no? For more complicated compositions or
> generic wires use banana brackets or the combinator syntax in arrow
> notation. Examples:
>
> myWire = proc x ->
> (someWire -< x) ^+^ (otherWire -< 15)
>
> myWire = proc x ->
> (| f (someWire -< x) (otherWire -< 15) |)
>
> This closely resembles idiom bracket notation, but allows you to be
> explicit about inputs, takes care of creating side channels and gives
> you the full power of arrows, including ArrowChoice and ArrowLoop.
>
>
> Greets,
> Ertugrul
>
> --
> nightmare = unsafePerformIO (getWrongWife >>= sex)
> http://ertes.de/
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20111212/fa72f7ba/attachment.htm>
More information about the Haskell-Cafe
mailing list