(背景:尝试学习Haskell,对函数式编程来说很陌生.通常用于Python.)
假设我有一个2元组列表,一个直方图:
let h = [(1,2),(3,5),(4,6),(5,3),(6,7),(7,4),(8,6),(9,1)]
Run Code Online (Sandbox Code Playgroud)
在命令性的术语中,我想将每对中的第二项更改为所有先前第二对的总和.在Python中,以下(公认的复杂)列表理解可以做到:
[(p[0], sum( [p[1] for p in histogram[:i+1]] ))
for i, p in enumerate(histogram)]
Run Code Online (Sandbox Code Playgroud)
假设histogram是指h如上所述的2元组列表.
这是我到目前为止在Haskell中所拥有的:
zip [fst p | p <- h] (scanl1 (+) [snd k | k <- h])
Run Code Online (Sandbox Code Playgroud)
这有效,但我想知道:
如果不清楚,这是上述的预期输出:
[(1,2),(3,7),(4,13),(5,16),(6,23),(7,27),(8,33),(9,34)]
Run Code Online (Sandbox Code Playgroud)
Lee*_*hem 11
你可以使用这个功能
accumulate = scanl1 step
where step (_,acc) (p1,p2) = (p1,acc+p2)
Run Code Online (Sandbox Code Playgroud)
以下是您的示例数据的结果:
*Main> accumulate h
[(1,2),(3,7),(4,13),(5,16),(6,23),(7,27),(8,33),(9,34)]
Run Code Online (Sandbox Code Playgroud)
如果你是Haskell的新手,这可能有点太早,但镜头提供了一个很好的简洁方法:
> scanl1Of (traverse . _2) (+) h
[(1,2),(3,7),(4,13),(5,16),(6,23),(7,27),(8,33),(9,34)]
Run Code Online (Sandbox Code Playgroud)
您可以通过切换到_1以下内容轻松累积第一个:
> scanl1Of (traverse . _1) (+) h
[(1,2),(4,5),(8,6),(13,3),(19,7),(26,4),(34,6),(43,1)]
Run Code Online (Sandbox Code Playgroud)
或者将所有值累积为一种嵌套列表:
> scanl1Of (traverse . both) (+) h
[(1,3),(6,11),(15,21),(26,29),(35,42),(49,53),(61,67),(76,77)]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
537 次 |
| 最近记录: |