ham*_*mar 19
对此的标准技巧是zip它自己的列表tail:
> let xs = [1,2,3,4] in zip xs (tail xs)
[(1,2),(2,3),(3,4)]
Run Code Online (Sandbox Code Playgroud)
要了解其工作原理,请在视觉上排列列表及其尾部.
xs = 1 : 2 : 3 : 4 : []
tail xs = 2 : 3 : 4 : []
Run Code Online (Sandbox Code Playgroud)
并注意到zip每列都有一个元组.
有两个更微妙的原因,为什么这总是正确的事情:
zip当任一列表用完元素时停止.这是有道理的,因为我们最终不能有一个"不完整的对",它也确保我们不会从单个元素列表中获得任何对.xs为空时,可能会tail xs抛出异常.但是,因为zip
首先检查它的第一个参数,当它看到它是空列表时,永远不会评估第二个参数.以上所有内容也适用于此zipWith,因此您可以在需要将函数成对应用于相邻元素时使用相同的方法.
对于像Clojure这样的通用解决方案partition,标准库中没有任何内容.但是,您可以尝试这样的事情:
partition' :: Int -> Int -> [a] -> [[a]]
partition' size offset
| size <= 0 = error "partition': size must be positive"
| offset <= 0 = error "partition': offset must be positive"
| otherwise = loop
where
loop :: [a] -> [[a]]
loop xs = case splitAt size xs of
-- If the second part is empty, we're at the end. But we might
-- have gotten less than we asked for, hence the check.
(ys, []) -> if length ys == size then [ys] else []
(ys, _ ) -> ys : loop (drop offset xs)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1208 次 |
| 最近记录: |