> module Circuits where > import Arrow > import Stream > import StreamArrow > import ArrowCircuit > import Monoid > import Automaton Some simple example circuits A resettable counter (first example in several Hawk papers): > counter :: ArrowCircuit a => a Bool Int > counter = proc reset -> do > rec output <- returnA -< if reset then 0 else next > next <- delay 0 -< output+1 > returnA -< output Some other basic circuits from the Hawk library. flush: when reset is True, return d for n ticks, otherwise copy value. (a variation on the resettable counter) > flush :: ArrowCircuit a => Int -> b -> a (b, Bool) b > flush n d = proc (value, reset) -> do > rec count <- returnA -< if reset then n else max (next-1) 0 > next <- delay 0 -< count > returnA -< if count > 0 then d else value latch: on each tick, return the last value for which reset was True, or init if there was none. > latch :: ArrowCircuit a => b -> a (b, Bool) b > latch init = proc (value, reset) -> do > rec out <- returnA -< if reset then value else last > last <- delay init -< out > returnA -< out Run a circuit on a partial input > partialRun :: ArrowRunCircuit a a' => a b c -> a' [b] [c] > partialRun f = proc xs -> do > s <- runCircuit f -< listToStream xs > returnA -< take (length xs) (streamToList s) Some tests using the counter > test_input = [True, False, True, False, False, True, False, True] A test of the resettable counter. > ts = partialRun (counter::StreamMap Bool Int) test_input > ta = partialRun (counter::Automaton (->) Bool Int) test_input A step function (cf current in Lustre) > step :: ArrowCircuit a => b -> a (Either b c) b > step b = proc x -> do > rec last_b <- delay b -< getLeft last_b x > returnA -< last_b > where getLeft _ (Left b) = b > getLeft b (Right _) = b