
Henning Thielemann wrote:
I want to connect several functions for signal processing. The typical case is that in a network of signal processor there are parts that are already discretized such as sampled sounds, and there are processors with no particular sample rate such as amplifiers. But when it comes to computation each processor must choose a sample rate for processing. There are also processors for converting sample rates. They divide the network into components of equal sample rate. The computation sample rate should be propagated through the network as follows: If in a component of equal sample rate some processors have the same fixed sample rate, all uncertain processors must adapt that. If some processors have different fixed sample rates this is an error. If no processor has a fixed sample rate, the user must provide one manually. To me this looks very similar to type inference. Is there some mechanism in Haskell which supports this programming structure?
If you define a class for sample rates, and an instance for each possible sample rate, then you could use type inference, e.g.
class Rate a where rate :: a -> Int;
data Rate22050 = Rate22050; instance Rate Rate22050 where rate _ = 22050;
data Rate44100 = Rate44100; instance Rate Rate44100 where rate _ = 44100;
data (Rate a) => Stream a = ...
type unaryProcessor a = (Rate a) => Stream a -> Stream a type binaryProcessor a = (Rate a) => Stream a -> Stream a -> Stream a ...
resample :: (Rate a, Rate b) => Stream a -> Stream b resample s = ...
Supporting arbitrary sample rates would require being able to construct a distinct type for every possible sample rate; e.g. using Church numerals:
data Rate0 = Rate0 instance Rate Rate0 where rate _ = 0;
data (Rate a) => RateN a instance (Rate a) => Rate (RateN a) where rate (RateN x) = 1 + rate x;
fourHertzFilter :: unaryProcessor (RateN (RateN (RateN (RateN Rate0)))) fourHertzFilter = ...
I doubt that this specific example wouldn't work in practice (the type
inference would probably give the compiler a heart attack), but you
could presumably construct an equivalent mechanism using base-N
numerals.
--
Glynn Clements