110 likes | 174 Views
600.429 FUNCTIONAL PROGRAMING AT WORK - HASKELL AND DOMAIN SPECIFIC LANGUAGES. Dr. John Peterson Western State Colorado University. This Week. Homework 6: Last questions? Homwork 7 should be ready to go later today. It will be due next Friday.
E N D
600.429FUNCTIONAL PROGRAMING AT WORK - HASKELL AND DOMAIN SPECIFIC LANGUAGES Dr. John Peterson Western State Colorado University
This Week Homework 6: Last questions? Homwork 7 should be ready to go later today. It will be due next Friday. Next Monday will be spent getting organized on the projects – come ready to work. I’ll be talking to each group during class.
SPJ! The God of Haskell will be here next week. Talk is at 11:15 – Be There!
A New FRP – Arrows! Problems with the original FRP: • No way to capture system inputs. The type Behavior a does not make the source of a explicit • Nasty implementation issues involving space / time leaks The solution: Arrows (Yay for Category Theory)
A New Abstraction • http://www.haskell.org/arrows/
Example: Stream Processors data Stream a b = Stream ([a] -> [b]) runS :: Stream a b -> [a] -> [b] runS (Stream f) inputs = f inputs instance Arrow Stream where arr g = Stream (map g) Stream f1 >>> Stream f2 = Stream (\input -> f2 (f1 input)) first (Stream f) = Stream (\s -> zip (f (map fst s)) (map snd s))
Euterpea Signal Processors The basic type is Clock c => SigFun c a b This allows different streams to have different sampling rates. Note that the arrow notation will require all components share a common clock You can explicitly upsample / downsample clocks using conversion functions
Oscillators osc :: Clock c => Table-> Double-> SigFunc () Double oscFixed:: Clock c => Double -> SigFunc () Double Tables are a fast way of representing functions They allow arbitrary functions to be pre-computed Instead of calculating values on the fly (sin and cosare computationally complex!)
Example: 3 Harmonics s :: Clock c => Sigfun c () Double s = proc () -> do f0 <- oscFixed 440 -< () f1 <- oscFixed880 -< () f2 <- oscFixed1320 -< () outA -< (f0 * 0.5 + f1 * 0.33 + f2 * 0.33)/1.83
Instruments reedyWav= tableSinesN 1024 [0.4, 0.3, 0.35, 0.5, 0.1, 0.2, 0.15, 0.0, 0.02, 0.05, 0.03] reed :: Instr (Stereo AudRate) reed durpchvolparams = let reedy = oscreedyWav0 freq = apToHzpch vel = fromIntegralvol / 127 / 3 env = envLineSeg [0, 1, 0.8, 0.6, 0.7, 0.6, 0] (replicate 6 (fromRationaldur/6))
Instruments in proc _ -> do amp <- env -< () r1 <- reedy -< freq r2 <- reedy -< freq + (0.023 * freq) r3 <- reedy -< freq + (0.019 * freq) let [a1, a2, a3] = map (* (amp * vel)) [r1, r2, r3] let rleft = a1 * 0.5 + a2 * 0.44 * 0.35 + a3 * 0.26 * 0.65 rright = a1 * 0.5 + a2 * 0.44 * 0.65 + a3 * 0.26 * 0.35 outA -< (rleft, rright)