
On Nov 28, 2006, at 7:46 AM, Slavomir Kaslev wrote:
Hello,
I have to define a couple of float2, float3, float4 Cg, HLSL style vectors in Haskell. At first I was tempted to make them instances of Num, Floating, RealFrac, etc. but some of the functions defined in those classes have no sense for vectors. One such example is signum from class Num.
There are several workarounds for this. One may come up with some meaning for vectors of such functions, for example:
instance Num Float3 where ..... signum a | a == Float3 0 0 0 = 0 | otherwise = 1
This is silly. Other option, which I prefer, is to leave such functions undefined (that is signum=undefined, not just not defining them). Is this ok? Are there any other options?
This will work. So long as you don't call signum, all will be well.
Another bugging thing is that some of the functions do have meaning for vectors but they need different signatures. For example (**) :: Floating a => a -> a -> a, for vectors should be (**) :: (Floating a, Vector v) => v -> a -> v, that is (**) applied for every component of the vector. Any workarounds for that?
I know that I can scrap all those Num, Floating, RealFrac, etc. classes and define class Vector from scratch, but I really don't want to come up and use different names for +, -, etc. that will bloat the code.
The inflexibility of the numeric classes is one of the well-known problems with the definition of the Haskell prelude. As you say, there are a number of things for which only a subset of the operations make sense, or where more general types are needed for the operations. There have been a couple of attempts to reformulate these classes so that they are more flexible. Here is one that I know of: http://darcs.haskell.org/numericprelude/ I haven't used it, so I can't really comment, other than to say it exists. I seem to recall that there were several other attempts in a similar vein, but my brief google search didn't turn them up. Can someone else fill in? If you want to roll your own, you can still use the nice names if you explicitly import the prelude and hide names. Eg, import Prelude hiding ( (+), (-), .... etc .... ) Hope that helps.
Last question: Does haskell have something like C++ templates? For example, some time in the future I may need types like int2, short3, etc., that behave just like float2, float3, but use different types for their components. I really, really wouldn't like to copy-paste the definitions of floatn and manually change their types to intn respectfully.
Cheers.
-- Slavomir Kaslev _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Speak softly and drive a Sherman tank. Laugh hard; it's a long way to the bank. -- TMBG