
Hello! Thank you very much for all your suggestions. A new version of the library can be found at: http://dis.um.es/~alberto/hmatrix/matrix.html Here are the main changes: - Vector and Matrix are now different types with different functions operating on them. They cannot be interchanged and we must use explicit conversion functions. Things like (v::Vector) + (m::Matrix), or svd (v::Vector) are statically rejected. You must use functions like matrix_x_matrix, matrix_x_vector, dot :: Vector->Vector->Double, etc. On the other hand, there are functions to build a matrix from a list of vectors, to concatenate the columns of a matrix as a vector, etc. If I am not mistaken, now the ambiguities explained by Henning do not occur. - Only Eq, Show, and Read instances are now defined for Vector and Matrix. No numeric instances are defined, although it is very easy to do it using the functions provided. I have included a tentative "Interface" module including some hopefully user friendly operators. But it can be replaced or deleted without any problem... :) If this approach makes sense, we can proceed to include more standard linear algebra functions based on GSL, LAPACK, or on any other available resource. We can use a darcs repository to allow contributions from all interested people. And a few comments: David Roundy wrote:
It would be wonderful if we could represent matrix multiplication as
matrix_mul :: Matrix n m -> Matrix m o -> Matrix n o
(where n, m and o are dimensions) but we can't do that. So we're stuck with dynamic size checking for all matrix and vector operations that involve two or more operands.
Lennart Augustsson wrote:
Actually, Haskell does allow you to do that. But the syntax of the types gets pretty horrendous.
We must also "add" types. To build a matrix from blocks we need something like: matrix_block_row :: Matrix n m -> Matrix n o -> Matrix n (o+m) I understand from some papers and messages to the list that it can be done, but then we may also want lists of matrices with different dimensions: matrix_block :: [[Matrix ? ?]] -> Matrix The compile-time consistency check is not trivial. On the other hand, many useful functions have a type which depends on a value: vector :: [Double] -> Vector n We should statically reject this: vector [1,2,3] `vector_add` vector [1,2] (or perhaps we can imitate the zip behavior? :) The sizes of some vectors and matrices depend on run time computations, even without taking into account IO: nullspace :: Matrix m n -> Matrix k n k depends on the particular matrix. We can improve this to: nullspace :: Matrix m n -> [Vector n] but if we need the nullspace in another matrix operation we must build a matrix from a list whose size is not known at compile time... Static size checking is an advanced topic! Alberto