Quote:Original post by jdh30
Quote:Original post by SamLowryBut I'll have to admit: O'Caml suffers from the same problem as C#: you won't be able to make one vector-"class" that would be perfectly parameterizable, working with integers and on floats (I already welcome jdh30 to this thread, ready to contradict this).
How's this:
module Make(Elt : sig type t val zero : t val one : t val ( ~: ) : t -> t val ( +: ) : t -> t -> t val ( -: ) : t -> t -> t val ( *: ) : t -> t -> t val ( /: ) : t -> t -> t val sqrt : t -> t end) = struct type t = Elt.t list open Elt open List let ( ~| ) = map ( ~: ) let ( +| ) = map2 ( +: ) let ( -| ) = map2 ( -: ) let ( *| ) s = map (( *: ) s) let ( *.| ) = fold_left2 (fun t a b -> t +: a *: b) zero let length2 r = r *.| r let length r = sqrt(length2 r)end;;
Cheers,
Jon.
That would indeed be a module of parameterizable vectors. I did think of modules, but for some reason I saw problems where there actually weren't any.
One little annoyance would be vector literals, but I guess that with the necessary helper functions it could be made as simple as "vector [5; 6; 3]" (I really don't want to have to type [Elt.one +: Elt.one +: Elt.one +: Elt.one +: Elt.one; Elt.one +: Elt.one +: Elt.one +: Elt.one +: Elt.one +: Elt.one; Elt.one +: Elt.one +: Elt.one])
Another annoyance would be the sort-of dynamic typing on the size of the vector: there's no compile-time check you are adding a 2D-vector with another 2D-vector. Of course, you could just define separate modules, but that would lead to duplication, and I don't like duplication. A solution I see is to have a module per kind of vector, with a hidden "type t = V2D of Elt.t list", a factory function "Vector2D.create x y = V2D [x;y]" and functions which retrieve the Elt.t list and pass it to a general VectorN module, but that would still require a lot of rather useless code. I'm currently not creative enough to find a truly elegant solution.