{- | Copyright : (c) Henning Thielemann 2008 License : GPL Maintainer : synthesizer@henning-thielemann.de Stability : provisional Portability : requires multi-parameter type classes Light-weight sample parameter inference which will fit most needs. We only do \"poor man's inference\", only for sample rates. The sample rate will be provided as an argument of a special type 'T'. This argument will almost never be passed explicitly but should be handled by operators analogous to '($)' and '(.)'. In contrast to the run-time inference approach, we have the static guarantee that the sample rate is fixed before passing a signal to the outside world. However we still need to make it safe that signals that are rendered for one sample rate are not processed with another sample rate. We should wrap @T s u t -> a@ in a @Reader@ monad, but that's not all. We must investigate a little more here. Maybe we need another type parameter for the sample rate and the signals in order to show that they belong together, like it is done in the ST monad. -} module Synthesizer.Dimensional.Rate where import qualified Number.DimensionTerm as DN import qualified Algebra.DimensionTerm as Dim import qualified Synthesizer.Utility as Util {- import NumericPrelude import PreludeBase as P -} {- | This wraps a function which computes a sample rate dependent result. Sample rate tells how many values per unit are stored for representation of a signal. -} newtype T s u t = Cons {decons :: DN.T (Dim.Recip u) t} deriving (Eq, Ord, Show) {-# INLINE fromNumber #-} fromNumber :: Dim.C u => Dim.Recip u -> t -> T s u t fromNumber u = Cons . DN.fromNumberWithDimension u {- | This function is somehow dangerous because it drops the 's' parameter. -} {-# INLINE toNumber #-} toNumber :: Dim.C u => Dim.Recip u -> T s u t -> t toNumber u = DN.toNumberWithDimension u . decons {-# INLINE fromDimensionNumber #-} fromDimensionNumber :: Dim.C u => DN.T (Dim.Recip u) t -> T s u t fromDimensionNumber = Cons {- | This function is somehow dangerous because it drops the 's' parameter. -} {-# INLINE toDimensionNumber #-} toDimensionNumber :: Dim.C u => T s u t -> DN.T (Dim.Recip u) t toDimensionNumber = decons {-# INLINE common #-} common :: Eq t => String -> T s u t -> T s u t -> T s u t common funcName = Util.common ("Sample rates differ in " ++ funcName)