take 和 drop 函数可能会在这里为您提供帮助。
drop, take :: Int -> [a] -> [a]
从这些我们可以构造一个函数来执行一个步骤。
takeNdropM :: Int -> Int -> [a] -> ([a], [a])
takeNdropM n m list = (take n list, drop (n+m) list)
然后我们可以用它来减少我们的问题
takeEveryNafterEveryM :: Int -> Int -> [a] -> [a]
takeEveryNafterEveryM n m [] = []
takeEveryNafterEveryM n m list = taken ++ takeEveryNafterEveryM n m rest
where
(taken, rest) = takeNdropM n m list
*Main> takeEveryNafterEveryM 5 3 [1..20]
[1,2,3,4,5,9,10,11,12,13,17,18,19,20]
由于这不是递归的原始形式,因此很难将其表示为简单的折叠。
因此可以定义一个新的折叠函数来满足您的需求
splitReduce :: ([a] -> ([a], [a])) -> [a] -> [a]
splitReduce f [] = []
splitReduce f list = left ++ splitReduce f right
where
(left, right) = f list
那么takeEveryNafterEveryM的定义很简单
takeEveryNafterEveryM2 n m = splitReduce (takeNdropM 5 3)