Udo Stenzel: >Bjorn Lisper wrote: >> Here is one way to do it. First, you have to interpret operations on >> matrices as being elementwise applied. E.g, (*) is interpreted as zipWith >> (zipWith (*)) rather than matrix multiply > >What's this, the principle of greatest surprise at work? Nonono, (*) >should be matrix multiplication, fromInteger x should be (x * I) and I >should be the identity matrix. Now all we need is an infinitely large >I, and that gives: > >instance Num a => Num [[a]] where > (+) = zipWith (zipWith (+)) > (-) = zipWith (zipWith (-)) > negate = map (map negate) > fromInteger x = fix (((x : repeat 0) :) . map (0:)) > m * n = [ [ sum $ zipWith (*) v w | w <- transpose n ] | v <- m ]
There are pros and cons, of course. Using (*) for matrix multiply is well-established in linear algebra. But: - it breaks the symmetry. This particular operator is then overloaded in a different way than all the others, and - your definition of fromInteger will behave strangely with the elementwise extended operations, like (+). 1 + [[1,2],[3,4]] will become [[2,2],[3,5]] rather than [[2,3],[4,5]]. Array languages supporting this kind of overloading invariably have the second form of semantics. Björn Lisper _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe