【发布时间】:2021-11-11 00:30:55
【问题描述】:
在 Haskell 中计算前缀和的简单方法是
scanl1 (+) [1,2,3,4,5,6]
产生输出
[1,3,6,10,15,21]
我需要写逆,这就是我想出的:
undo_prefix_sum :: (Num a) => [a] -> [a]
undo_prefix_sum s = init $ snd $
foldr (\cur (tot, l) -> (cur, (tot-cur):l))
(last s, [])
(0:s)
这似乎是正确的(但我可能错过了一些东西)。 有没有更简单或更有效的方法来做到这一点,可能使用扫描?
【问题讨论】:
-
您在另一条评论中提到了
zipWith (-) xs (0:xs),并“照亮了 Haskell 的有趣部分”。如果您还没有看到zipWith (-) <*> (0 :) $ [1..6],您可能会有所启发。 -
谢谢。我在这方面的经历很像我对"juxt" in haskell 的经历。在这种情况下,函数的
<*>定义使用了它的参数两次;在另一个中,函数的 Reader monad 实例被牵连,这与多次使用参数的效果相似! -
scanl1 (+)不计算前缀总和。它计算前缀总和。 -
@MichaWiedenmann 在 GHCI 中
scanl1 (+) [1..20]之后尝试zipWith (-) <*> (0 :) $ it。 (等待它...)然后尝试zipWith (-) <*> (0 :) $ it再次。然后再次。然后再次。 :) 然后再次。 :) 我不知道照明,但它很有趣。 -
@WillNess 感谢分享!确实很有趣。
标签: haskell prefix-sum