# public eightyeight / feedback.hs Last active 2013-10-25

Testing Yampa with simple examples.

feedback.hs
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 `import FRP.Yampa -- A feedback loop of the standard form from the link below.system = feedback (-) (gain 5) (gain 0.1) 0 -- Construct a feedback loop with forward function 'a', reverse function 'b',-- combine with 'f', and initial feedback value 'b0'.-- http://upload.wikimedia.org/wikipedia/commons/e/ed/Ideal_feedback_model.svgfeedback :: (a -> a -> a) -> SF a a -> SF a a -> a -> SF a afeedback f a b b0 = loopPre b0 inner where -- The inner function has two inputs and two outputs. Passing it to -- 'loopPre' produces a function with one input and one output, because -- inner's second output is connected to its second input. inner = unsplit >>> a >>> identity &&& b -- Combine elements of a tuple using 'f'. unsplit = arr \$ \t -> fst t `f` snd t main = print \$ embed fn signal where fn = system signal = deltaEncode dt [start .. end] dt = 0.1 start = 1 end = 10 gain x = arr (*x)`
simple.hs
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 `import FRP.Yampa -- Read 'SF' as 'signal function'. An 'SF Int Int' is therefore a signal with an-- Int input and an Int output. This line just declares a type and is optional.-- Haskell can normally deduce types automatically.system :: SF Int Int -- Our system is a composition of two other stream functions glued together-- output-to-input.system = gain 3 >>> offset 1 -- These functions construct signal functions from an int.gain, offset :: Int -> SF Int Int -- 'arr' turns regular functions into 'arrows', an abstraction which Yampa uses-- to compose signal functions.gain x = arr (*x)offset x = arr (+x) -- Run a signal through the system.main = print \$ embed fn signal where fn = system signal = deltaEncode dt [0 .. end] dt = 0.1 end = 10`
spring.hs
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 `import FRP.Yampaimport Graphics.Gnuplot.Simple system = force >>> displacement force = constant (m * g) displacement = feedback (-) (velocity >>> integrate) (gain \$ k / m) 0velocity = feedback (-) (integrate) (gain \$ c / m) 0 m, g, k, c :: Doublem = 1g = 9.81k = 10c = 1 main = plotPath [] (embed fn signal) where -- 'time' again integrates the timestep to provide a definite output time -- at each step, which we pass through to the output for plotting. fn = time >>> pass &&& system steps = 50 dt = 0.1 signal = deltaEncode dt \$ replicate steps 0 integrate = imIntegral 0 pass = identity gain x = arr (*x) feedback op a b b0 = loopPre b0 inner where inner = arr (uncurry op) >>> a >>> (identity &&& b)`
time.hs
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 `import FRP.Yampaimport Text.Printf -- 'time' outputs a constantly-increasing value representing the accumulated-- time. The 'dt' value in the main function determines the timestep, encoded-- into the signal and ignored in the previous examples. Here we make a-- contrived example that generates values of sin(t).system :: SF Time Doublesystem = time >>> arr sin -- Use pretty printing!main = mapM_ (printf "%.3f\n") \$ embed fn signal where fn = system steps = 4 dt = pi / steps signal = deltaEncode dt [0 .. steps]`