
On Tue, Jun 17, 2008 at 04:04:11PM +0100, Olex P wrote:
Hi guys,
Sorry for a silly questions but I didn't find a proper answer in Google. I've started to learn Haskell and would like to implement a library for work with vectors. I found different implementations of this stuff but all of them made just for fun in a short as possible terms using lists or tuples. I suppose there should be a better way to go. First idea came to my mind was using of classes. Something like this:
[code] -- Template Vector class
class Vector v where (<+>) :: v -> v -> v (<->) :: v -> v -> v (<*>) :: v -> v -> v (*>) :: v -> Float -> v -- other methods here
-- Vector3 instance
-- Declare new Vector3 type
data Vector3 = Vector3 (Float, Float, Float)
instance Vector Vector3 where (<+>) (Vector3 (x1, y1, z1)) (Vector3 (x2, y2, z2)) = Vector3 (x1 + x2, y1 + y2, z1 + z2) (<->) (Vector3 (x1, y1, z1)) (Vector3 (x2, y2, z2)) = Vector3 (x1 - x2, y1 - y2, z1 - z2) (<*>) (Vector3 (x1, y1, z1)) (Vector3 (x2, y2, z2)) = Vector3 (x1 * x2, y1 * y2, z1 * z2) (*>) (Vector3 (x, y, z)) f = Vector3 (x * f, y * f, z * f) length (Vector3 (x, y, z)) = sqrt (x * x + y * y + z * z) -- the rest of methods [/code]
, == etc.) Is it good idea to use classes and ad hoc polymorphism or better to use
What I don't like here is using of data type constructors when even simple expression like v1 + v2 becomes too long (<+>) (Vector3 (1,2,3)) (Vector3 (4,5,6)) Do I really need a data type constructor (in this particular case)? Or better to declare a vector3 type as: type Vector3 = (Float, Float, Float)? Next question is how to make one instance which derives from several classes? For example from Eq, Num and Vector (if I want to overload +, -, <, parametric polymorphism? How you would implement such library? (not just for educational purposes but for development of _very_good_extensible_ software)
Well, The type I would use for Vector3 is data Vector3 = Vector3 !Float !Float !Float That will give you 3 strict (and perhaps unboxed) floats and reduce your need for parenthesis. In general, real types (declared with data or newtype) are a good idea, they often allow compiler optimizations, make your code more robust, and provide nice abstraction capabilities. The 'newtype deriving' extension is particularly useful. You can also create helper functions like v3 = Vector3 so you can do (v3 1 2 3 <+> v3 4 5 6) John -- John Meacham - ⑆repetae.net⑆john⑈