Netwire
From HaskellWiki
(Difference between revisions)
(→Basics) |
(→Running wires) |
||
| Line 87: | Line 87: | ||
loop w -- loop with the new wire. | loop w -- loop with the new wire. | ||
| + | </haskell> | ||
| + | |||
| + | Note: Even though the FRP idea suggests it, there is no reason to run wires continuously or even regularly. You can totally have an instant depending on user input, a GUI event or network traffic, so instants can be minutes apart. | ||
| + | |||
| + | === Testing wires === | ||
| + | |||
| + | There is a convenient function for testing wires, which does all the plumbing for you. It's called <hask>testWireM</hask>: | ||
| + | |||
| + | <haskell> | ||
| + | testWireM :: | ||
| + | (Show e, MonadIO m) | ||
| + | => Int | ||
| + | -> m a | ||
| + | -> Wire e (Kleisli m) a String | ||
| + | -> m () | ||
| + | </haskell> | ||
| + | |||
| + | For wires returning a string, you can easily test them using this function. The first argument is a FPS/accuracy tradeoff. If it's 100, it will only print the output of every 100th instant. The second argument is an input generator action. At each instant, this action is run and its result is passed as input to the wire. The wire's output is then printed. <hask>testWireM</hask> prints the output continuously on a single line: | ||
| + | |||
| + | <haskell> | ||
| + | main :: IO () | ||
| + | main = testWireM 1000 (return 15) system | ||
</haskell> | </haskell> | ||
[[Category:FRP]] | [[Category:FRP]] | ||
Revision as of 16:25, 1 December 2011
Netwire is a library for functional reactive programming, which uses the concept of arrows for modelling an embedded domain-specific language. This language lets you express reactive systems, which means systems that change over time. It shares the basic concept with Yampa and its fork Animas, but it is itself not a fork and has many additional features.
This wiki page corresponds to Netwire version 3 and is currently a work in progress.
Contents |
1 Features
Here is a list of some of the features of Netwire:
- arrow interface (or optionally an applicative interface),
- signal inhibition (ArrowZero / Alternative),
- signal selection (ArrowPlus / Alternative),
- self-adjusting wires (ArrowChoice),
- rich set of event wires,
- signal analysis wires (average, peak, etc.),
- effectful wires.
2 Basics
The Netwire library is based around a data type calledWire
Control.Wire
import Control.Wire data Wire e (>~) a b
(>~)
e
Wire e (>~)
(>~)
Wire
comp :: Wire e (>~) a b
Wire e (>~) a b
a >~ Either e b
a
b
e
2.1 The inhibition monoid
Thee
Wire
()
()
2.2 Base arrows
The(>~)
Wire
Kleisli
IO
type MyWire = Wire () (Kleisli IO)
3 Running wires
For running a wire you can use the stepping functions available in theControl.Wire.Session
Control.Wire
stepWireM
stepWireM :: Monad m => Wire e (Kleisli m) a b -> a -> m (Either e b, Wire e (Kleisli m) a b)
m = IO
stepWireM :: MyWire a b -> a -> IO (Either () b, MyWire a b)
Either () b
stepWireM
system :: MyWire Int String system = {- ... -} main :: IO () main = loop system where loop :: MyWire Int String -> IO () loop w' = do (mx, w) <- stepWireM w' 15 {- ... do something with mx ... -} loop w -- loop with the new wire.
Note: Even though the FRP idea suggests it, there is no reason to run wires continuously or even regularly. You can totally have an instant depending on user input, a GUI event or network traffic, so instants can be minutes apart.
3.1 Testing wires
There is a convenient function for testing wires, which does all the plumbing for you. It's calledtestWireM
testWireM :: (Show e, MonadIO m) => Int -> m a -> Wire e (Kleisli m) a String -> m ()
testWireM
main :: IO () main = testWireM 1000 (return 15) system
