haskell - 为什么 sum == foldl1 (+) 不是?

标签 haskell matrix sum fold foldable

我将矩阵列表与 foldl1 (+) 相加因为我注意到 sum实际上将左上角元素的总和作为 1x1 矩阵返回。

$ 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 │
└   ┘

这出乎我的意料,LYAH 建议 sum = foldl1 (+) ¹ 甚至 hlint 建议我使用 sum而不是 foldl1 (+) as is '删除 [] 上的错误'(附带问题:我如何优雅地 [] - 安全地总结矩阵?)

为什么是 sum /= foldl1 (+)对于矩阵,为什么通常不总是 sum == foldl1 (+) ?

或者,排除空列表的情况:

为什么不是 sum == foldl neutralElement (+) ?或具体sum == foldl (+) (zero 2 2)[identity 2, identity 2] ?

自己的工作:
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’

来源sum是:
sum :: Num a => t a -> a
sum = getSum #. foldMap Sum
Matrix 的实例化是:
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.
 ...

¹ 在添加整数的情况下

最佳答案

因为Data.Matrix Num 的实例实现 fromInteger通过返回一个 1x1 矩阵和 +通过添加 elementwise它将右侧矩阵截断为左侧矩阵的大小(如果左侧大于右侧则错误)。
sumfoldl (+) 00 中的 1x1 矩阵开始并将列表中的所有矩阵截断为该大小。 foldl1 (+)不必从整数生成矩阵,因此结果是列表中最小矩阵的大小。

另外,sum = getSum #. foldMap Sum是默认值 Foldable实现,但它被列表实例覆盖为 sum = foldl (+) 0 .
Data.Matrix +的实现(如上所示)如果操作数不是相同的形状,直到版本 0.3.1.1 会生成错误,但在版本 0.3.2.0 中它假定它们是相同的形状而不检查,并且在版本 0.3.3.0 中它再次更改(根据评论):

-- | Perform an operation element-wise.
--   The second matrix must have at least as many rows
--   and columns as the first matrix. If it's bigger,
--   the leftover items will be ignored.
--   If it's smaller, it will cause a run-time error.
--   You may want to use 'elementwiseUnsafe' if you
--   are definitely sure that a run-time error won't
--   arise.

实现似乎与当前版本 0.3.6.1 相同

关于haskell - 为什么 sum == foldl1 (+) 不是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57524983/

相关文章:

list - 如何使用自定义版本的List : `data List a = Nil | Cons a (List a)` ?

Haskell,创建一个给定特定类型的函数

data-structures - 将非类型化 Lisp 数据映射为类型化二进制格式以用于编译函数

java - 使用 ThreadPool 并行化矩阵乘法

r - 识别匹配给定字符串向量的列索引

mysql - Sum 使我的查询结果相乘

php - 从两个不同的表中获取两列的总和

haskell - Haskell中由常量参数化的数据类型

python - 如何使用 numpy 找到两个非常大的矩阵的行之间的成对差异?

c# - 多维数组中值的快速求和 (C#)