Solution (source code)

= Solution

Reuse `dimensions` and either <transpose> definition above:
``
multMat :: Num a => Matrix a -> Matrix a -> Matrix a
multMat a b
  | colsA /= rowsB = error "multMat: incompatible sizes"
  | otherwise = [[sum (zipWith (*) row col) | col <- columnsB]
                                           | row <- a]
  where
    (_,colsA) = dimensions a
    (rowsB,_) = dimensions b
    columnsB = transpose b
``
For $A$ of size $m\times n$ and $B$ of size $n\times p$, every selected row and column has length $n$. Their <dot product> is
$$
\boxed{(AB)_{ij}=\sum_{k=1}^{n}a_{ik}b_{kj}}.
$$
The two <list comprehensions> place this entry in row $i$, column $j$ of an $m\times p$ result. The dimension guard checks exactly the compatibility condition for <matrix multiplication>. The shared `columnsB` avoids recomputing the <transpose> for each row; the arithmetic cost is $\Theta(mnp)$ in the unit-cost model.