I sum a list of matrices with foldl1 (+)
because I noticed that sum
actually returns the sum of the top left elements as a 1x1 matrix.
$ stack exec --resolver lts-12.5 --package matrix -- ghci
GHCi, version 8.4.3: http://www.haskell.org/ghc/ :? for help
Prelude> import Data.Matrix
Prelude Data.Matrix> t = [identity 2, identity 2] -- two 2x2 identity matrices
Prelude Data.Matrix> foldl1 (+) t
┌ ┐
│ 2 0 │
│ 0 2 │
└ ┘
Prelude Data.Matrix> sum t
┌ ┐
│ 2 │
└ ┘
This is unexpected for me, LYAH suggests sum = foldl1 (+)
¹ and even hlint suggests I use sum
instead of foldl1 (+)
as is 'removes error on []
' (side question: How do I elegantly and []
-safely sum up matrices?)
Why is sum /= foldl1 (+)
for Matrices, and why isn't generally always sum == foldl1 (+)
?
Or, to exclude the case of the empty list:
Why isn't sum == foldl neutralElement (+)
? or specifically sum == foldl (+) (zero 2 2)
on [identity 2, identity 2]
?
Own work:
Prelude Data.Matrix> :t sum
sum :: (Foldable t, Num a) => t a -> a
Prelude Data.Matrix> :info sum
class Foldable (t :: * -> *) where
...
sum :: Num a => t a -> a
...
-- Defined in ‘Data.Foldable’
Source of sum
is:
sum :: Num a => t a -> a
sum = getSum #. foldMap Sum
Instantiations of Matrix
are:
instance Foldable Matrix where
foldMap f = foldMap f . mvect
instance Num a => Num (Matrix a) where
fromInteger = M 1 1 . V.singleton . fromInteger
negate = fmap negate
abs = fmap abs
signum = fmap signum
-- Addition of matrices.
{-# SPECIALIZE (+) :: Matrix Double -> Matrix Double -> Matrix Double #-}
{-# SPECIALIZE (+) :: Matrix Int -> Matrix Int -> Matrix Int #-}
(M n m v) + (M n' m' v')
-- Checking that sizes match...
| n /= n' || m /= m' = error $ "Addition of " ++ sizeStr n m ++ " and "
++ sizeStr n' m' ++ " matrices."
-- Otherwise, trivial zip.
| otherwise = M n m $ V.zipWith (+) v v'
-- Substraction of matrices.
...
-- Multiplication of matrices.
...
¹ in the context of adding integers
fromInteger 0
, sosum = getSum #. foldMap Sum
. – NomismNum
instance for matrices at all. Then bothsum
andfoldl1 (+)
would be errors, as they should be. (The particular property you are probably implicitly assuming here that is not validated by the existingNum
instance isx + 0 = 0 + x = x
.) – Bravinsum = foldl (+) (zero 2 2)
on your list, butsum = foldl (+) (zero 57 19)
on a different list? What size matrix do you expectsum [] :: Matrix Int
to return? The behavior you want would clearly need matrix-specific behavior that you're not going to get out of the generalFoldable
instance of lists. – Detergent