
Well, I may not exactly qualify, but I can give you a few suggestions, nonetheless...
Thanks!
data Floating a => Vector a = Vector !a !a !a deriving (Eq, Show)
Here. Do not use 'data C x =>'. It's essentially a useless part of the language that really should have gone away. What you want is just: | data Vector a = Vector !a !a !a deriving (Eq, Show)
The Floating constraint can come in on the functions.
(I say this feature is useless because it only does one thing: disallows you to construct Vectors whose elements aren't instances of Floating. However, the useful thing that it might do -- namely, allow you to *use* the fact that the elements are instances of Floating -- it doesn't.)
That was indeed what I expected it would do. Is there any reason why it doesn't, other than historical accident? It looks like a useful feature to me.
There are actually two problems. First, you want to write fmod as: | fmod x y = x - y * fromInteger (truncate (x/y))
OK, that's obvious.
otherwise the type is wrong. Secondly, since you're using truncate, you
need to be in RealFrac, not in Floating. Changing the signature to: | instance RealFrac a => ...
fixes this problem.
OK, that looks reasonable too (but the multitude of number classes does not yet look reasonable to me - I'll have to print a description and put it next to my keyboard).
And here's the problem. When 'u' is 'OrthorhombicUniverse x', it doesn't know that this 'x' is supposed to be the same as the 'a'. One
Indeed...
way to fix this is to parameterize the Universe data type on the element, something like:
OK, that works. But it doesn't make my code any nice, it means many more type constraints all over the code.
This is beginning to get a little ugly, but I think that's largely because you're using type classes in too much of an OO style (this is
I am coming from OO indeed...
similar to this, I moved away from that). However, not knowing more about the domain of discourse, I don't know what to suggest. Perhaps using the module system would serve you better. Instead of having a universe class, simply put each universe in a separate module and provide the same functions in each. Then you just import them selectively, or qualified.
I don't think this would be appropriate to me. I want to be able to use multiple universe types in the same program, but qualified imports are not a solution either, as there will be a lot of code referring to generic universes. More fundamentally, I consider the module system in its present form a major weak point of Haskell. There is only one global module namespace, which therefore is a scarce resource. If, as I have seen proposed in some book, I use up a global module name for each abstract data type, then I can almost expect to get name clashes as soon as I try to use my code together with someone else's (who thought that "vector" would be a great name for something slightly different). I have seen the proposal for hierarchical libraries, but that seems to be no more than a proposal at the moment. My intention is to write rather low-level library-style code for a specific yet wide application domain (scientific computing), which explains the need for generality. I haven't seen this issue addressed in any of the Haskell books or Web sites I know, so I would appreciate any pointers. It's a difficult problem for many languages, in fact I suspect that it's the main reason why languages like Fortran or C++ never got to the point of having sufficiently general libraries (I stopped counting the C++ matrix libraries, for example). Konrad.