5

我写了一个函数来分离隔行扫描的元素。

interlacedElems :: [a] -> ([a], [a])
interlacedElems xs = (f xs, f $ tail xs)
   where f (x:_:xs) = x : f xs
         f x = x

main = print $ interlacedElems "a1b2c3d4"

产生的输出:

("abcd","1234")

在我的代码中,我定义f并使用了两次,有效地递归了同一个列表两次,但每次都略有不同。

我的问题是:有没有办法可以写这个,所以我只在列表中递归一次?因为那样会更有效率,你不觉得吗?

我试图弄清楚我的一些大脑泄漏了,然后我妈妈告诉了我,因为她说我总是把脑汁弄得到处都是,而且要花很长时间才能把地毯上的粉红色污渍弄掉。

谢谢好心人:)

4

2 回答 2

9

你也可以foldr使用这个技巧来做到这一点:

interlacedElems :: [a] -> ([a], [a])
interlacedElems = foldr (\x ~(l,r) -> (x:r,l)) ([],[])

笔记

无可辩驳的模式~(l,r)使其适用于无限列表。

于 2013-10-26T21:55:42.203 回答
2

我只想编写一个函数,递归地将列表拆分为元组,然后使用unzip

listToTuples :: [a] -> [(a, a)]
listToTuples (x:y:xs) = (x, y) : listToTuples xs
listToTuples _ = []

interlacedElems :: [a] -> ([a], [a])
interlacedElems = unzip . listToTuples
于 2013-10-26T21:36:13.430 回答