let mmul = (\(A,B) :: (Arr (Int,Int) Float, Arr (Int,Int) Float) ->
-- zip all combinations of rows from A and cols from B
let R1 = eqJoinArr (snd, fst A, B) in
-- multiply values from A and B
let R2 = mapArrInv (id, Float.*, id, R1) in
-- group by dest & sum-reduce
let C = groupReduceArr (\((ai,aj),(bi,bj)) -> (ai,bj),
snd, Float.+, R2) in C) in ...