我发现自己经常使用一种模式,在该模式下,我使用一个使用列表中的1..n元素并从中产生一些结果的函数来转换列表。例如。

process :: [a] -> [b]
process [] = []
process xs = first : rest
    where (first, xs') = consume xs
          rest         = process xs'


consume函数使用列表中可变数量的项目,并返回结果和其余列表项目。我可以在这里使用一些标准的高阶函数来代替显式递归吗?

最佳答案

您需要的功能类似于unfoldr。如果您将consume带入以下格式:

consume' :: [a] -> Maybe (b,[a])


如果列表为空,则consume'返回Nothing,否则为Just ...。这是一个小包装,捕获了该模式:

wrap :: ([a] -> (b,[a])) -> [a] -> Maybe (b,[a])
wrap f [] = Nothing
wrap f xs = Just $ f xs


然后,您可以将consumeunfoldr一起使用,而consume :: [a] -> (b,[a])的原始定义如下:

unfoldr (wrap consume)

10-06 10:30