
- u create a class "Y" to tackle the "zero" problem for different kinds of y vectors in a common way
Yes.
- u create a "Signal" class for the Y- signal inheriting interfaces from y and Storable.Storable
I wouldn't say "inheriting". It puts a restriction on 'y' saying that it has to be in Storable as well. That's unnecessary, but it saves me from having to put the restriction in all the places I use 'y'. I.e., the class below is not necessary, all it does is that instead of typing 'Storable (X, y), Y y' I can simply type 'Signal y'. So it's like a type alias for classes, except a little awkward because you need some bogus instances: class (Storable.Storable (X, y), Y y) => Signal y I don't know if it's a good idea or not, I just got tired of ugly signatures.
Then u nest X and Y in a V.Vector - array and give it the type synonym SigVec. In all of this X and Y are ur types (or type synonyms) and y is a help variable.
Sorry, there's some missing context which might make this more confusing. In SignalBase, X is a type but y is a type variable. Y is a type class that constrains the type variable 'y' (it could be named 'a' or 'b' or anything else). In SignalBase, 'at' has this signature: at :: (Signal y) => X -> SigVec y -> y Then in Signal, there is a concrete definition for 'y' called Y: newtype Signal = Signal { sig_vec :: SignalBase.SigVec Y } type X = SignalBase.X type Y = Double instance SignalBase.Signal Y -- To make the bogus empty instance for Signal happy, I have its requirements: instance Storable.Storable (X, Y) where sizeOf _ = Storable.sizeOf (undefined :: RealTime) + Storable.sizeOf (undefined :: Double) ... etc. instance SignalBase.Y Y where zero_y = 0 ... -- Now the 'at' in this module looks like: at :: X -> Signal -> Y at x sig = SignalBase.at x (sig_vec sig) I took out the phantom variable 'y' since that's orthogonal (though it's useful if you want to have several different types that can support the same operations).
- I read using composite datatype using the "data" keyword makes code rather slow - is nesting better ? : e.g. "data Signal Double v.Vector" versus "newtype (Double, v.Vector)
They're the same, a tuple is an indirection just like a two argument 'data'. And another pointer to follow in the middle is probably not going to make your code slow. If space saving is very important, you can eliminate it with the UNPACK pragma, but only think about that if you're storing very large numbers of them.
- which nesting structure is most efficient - touples, lists, V.vector, ...
Depends. The various unboxed vectors are efficient for memory and large scale transformation, lists are efficient for manipulating the front and are lazy on every single element and don't need Storable instances.