Bjorn Lisper lisper at it.kth.se
Thu Jun 22 09:37:42 EDT 2006

```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