所以,我在编写一个程序时遇到了很多麻烦,这个程序是从几个大的整数向量中生成一个协方差矩阵,存储在不同的文件中.我从写作开始
mean xs = realToFrac (sum xs) / realToFrac (length xs)
cov xs ys = mean (zipWith (*) xs ys) - mean xs * mean ys
covmat vectors = [cov xs ys | ys <- vectors, xs <- vectors]
Run Code Online (Sandbox Code Playgroud)
它适用于小输入,但你可以看到即使只是"意味着"也是多么低效.它在执行总和时将所有x保留在内存中,因为它们将被"length"使用.这是可以修复的,如下:
mean xs = realToFrac thisSum / realToFrac thisLength
where (thisSum, thisLength) = foldl' (\(s,l) y-> (s+y,l+1)) (0,0) xs
Run Code Online (Sandbox Code Playgroud)
但后来我遇到了与"cov"相同的问题.当我用这种风格改写"cov"时,它并没有最终使用我的"平均"功能.当我编写"covmat"函数时,我仍然有一个级别,这将变得非常复杂.
所以,我有两个目标,似乎有冲突:
遍历每个列表一次,而不将其保留在内存中
将"covmat"分解为更简单,更有意义的功能,特别是"cov"和"mean"
我没有看到任何方法将这两个目标与我对Haskell的了解统一起来.但从概念上看似乎很简单:所有这些函数都需要"监听"它们进入的相同几个列表的值.在Haskell中有没有办法像这样组织它?如果这需要不同的数据结构或额外的库,我对此持开放态度.
haskell ×1