module Signal.Example where import Control.Monad (forM_) import Signal -------------------------------------------- -- Examples -- | sinusoidal of given frequency sinS :: Double -> Signal Double sinS freq = mapT (freq*) $ mapS sin $ timeS main :: IO () main = magic $ sinS 0.3 -- Problem: averaging two signals? -- averageS :: Fractional a => -- Signal a -> Signal a -> Signal a -- averageS = ... Fill in a definition here ... -- Hint: use the average function, mapS and $$ combinators. average :: Fractional a => a -> a -> a average x y = (x + y) / 2.0 scale :: Num a => Signal a -> Signal a scale = mapS ((30*) . (1+)) -- | Discretize a signal discretize :: Signal Double -> Signal Int discretize = mapS round -- | convert to "analog" toBars :: Signal Int -> Signal String toBars = mapS (\x -> replicate x '#') displayLength = 100 -- | display the signal at a number of points display :: Signal String -> IO () display ss = forM_ [0..displayLength] $ \x -> putStrLn (sample ss x) -- The display magic. -- Note how we take advantage of function composition, -- types defined so far, etc. magic :: Signal Double -> IO () magic = display . toBars . discretize . scale ---------------------------------------------------- -- Answer to exercise averageS :: Fractional a => Signal a -> Signal a -> Signal a averageS xs ys = mapS average xs $$ ys -- It can also be generalised to an arbitray Applicative functor averageA :: (Fractional a, Applicative f) => f a -> f a -> f a averageA xs ys = average <$> xs <*> ys -- or slightly shorter averageA' :: (Fractional a, Applicative f) => f a -> f a -> f a averageA' = liftA2 average -- Control.Applicative: -- http://haskell.org/ghc/docs/6.10.4/html/libraries/base/Control-Applicative.html