哈斯克尔中列表的点积



我正在尝试仅使用Prelude库中的函数在两个数字列表之间实现点积。我编写了以下函数:

dot :: Num a => [a] -> [a] -> a
dot x y = sum $ zipWith (*) x y

我测试如下:

main :: IO ()
main = do
    let n = 10^6
        x = (replicate n 2.0) :: [Double]
        y = (replicate n 3.0) :: [Double]
    print $ dot x y
    return ()

不幸的是,此代码会导致包含 100 万个元素的列表的堆栈空间溢出(使用 ghc 7.6.3 和优化标志 -O2)。

对于这样一个简单的情况,我本来希望ghc能够执行必要的优化,以避免递归调用的成本。我错过了什么吗?我的实现有误吗?

sum(过去)是用foldr实现的。对于大多数Num实例来说,这是一个有点愚蠢的选择;严格的左折更好。用

import Data.List
sum' :: Num a => [a] -> a
sum' = foldl' (+) 0

相反,您的堆栈溢出将消失。

相关内容

  • 没有找到相关文章

最新更新