Note that there are some explanatory texts on larger screens.

plurals
  1. POWrite this Scala Matrix multiplication in Haskell
    primarykey
    data
    text
    <blockquote> <p><strong>Possible Duplicate:</strong><br> <a href="https://stackoverflow.com/questions/8308015/can-you-overload-in-haskell">Can you overload + in haskell?</a> </p> </blockquote> <p>Can you implement a Matrix class and an * operator that will work on two matrices?:</p> <pre><code>scala&gt; val x = Matrix(3, 1,2,3,4,5,6) x: Matrix = [1.0, 2.0, 3.0] [4.0, 5.0, 6.0] scala&gt; x*x.transpose res0: Matrix = [14.0, 32.0] [32.0, 77.0] </code></pre> <p>and just so people don't say that it's hard, here is the Scala implementation (courtesy of <a href="http://jsmerritt.blogspot.com/2008/07/matrix-multiplication-in-scala.html" rel="nofollow noreferrer">Jonathan Merritt</a>):</p> <pre><code>class Matrix(els: List[List[Double]]) { /** elements of the matrix, stored as a list of its rows */ val elements: List[List[Double]] = els def nRows: Int = elements.length def nCols: Int = if (elements.isEmpty) 0 else elements.head.length /** all rows of the matrix must have the same number of columns */ require(elements.forall(_.length == nCols)) /* Add to each elem of matrix */ private def addRows(a: List[Double], b: List[Double]): List[Double] = List.map2(a,b)(_+_) private def subRows(a: List[Double], b: List[Double]):List[Double] = List.map2(a,b)(_-_) def +(other: Matrix): Matrix = { require((other.nRows == nRows) &amp;&amp; (other.nCols == nCols)) new Matrix( List.map2(elements, other.elements) (addRows(_,_)) ) } def -(other: Matrix): Matrix = { require((other.nRows == nRows) &amp;&amp; (other.nCols == nCols)) new Matrix( List.map2(elements, other.elements) (subRows(_,_)) ) } def transpose(): Matrix = new Matrix(List.transpose(elements)) private def dotVectors(a: List[Double], b: List[Double]): Double = { val multipliedElements = List.map2(a,b)(_*_) (0.0 /: multipliedElements)(_+_) } def *(other: Matrix): Matrix = { require(nCols == other.nRows) val t = other.transpose() new Matrix( for (row &lt;- elements) yield { for (otherCol &lt;- t.elements) yield dotVectors(row, otherCol) } ) override def toString(): String = { val rowStrings = for (row &lt;- elements) yield row.mkString("[", ", ", "]") rowStrings.mkString("", "\n", "\n") } } /* Matrix constructor from a bunch of numbers */ object Matrix { def apply(nCols: Int, els: Double*):Matrix = { def splitRowsWorker( inList: List[Double], working: List[List[Double]]): List[List[Double]] = if (inList.isEmpty) working else { val (a, b) = inList.splitAt(nCols) splitRowsWorker(b, working + a) } def splitRows(inList: List[Double]) = splitRowsWorker(inList, List[List[Double]]()) val rows: List[List[Double]] = splitRows(els.toList) new Matrix(rows) } } </code></pre> <p><strong>EDIT</strong> I understood that strictly speaking the answer is No: overloading * is not possible without side-effects of defining also a + and others or special tricks. The <a href="http://hackage.haskell.org/package/numeric-prelude" rel="nofollow noreferrer">numeric-prelude package</a> describes it best:</p> <blockquote> <p>In some cases, the hierarchy is not finely-grained enough: Operations that are often defined independently are lumped together. For instance, in a financial application one might want a type "Dollar", or in a graphics application one might want a type "Vector". It is reasonable to add two Vectors or Dollars, but not, in general, reasonable to multiply them. But the programmer is currently forced to define a method for '(*)' when she defines a method for '(+)'.</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload