4

我很好奇以下示例是否可以使用列表推导代替递归。

replaceFirst接受一个元素和一个列表并替换列表中第一次出现的元素的函数。

这可以使用递归来完成,如下所示:

replaceFirst _ [] = []
replaceFirst elem y (x:xs) | x==y = (elem:xs)
                           | otherwise = x:replaceFirst elem y xs

我的问题是,这个递归函数,或者类似的对列表中第一次出现的元素进行操作的递归函数可以替换为列表理解函数吗?为什么或者为什么不?(我更关心推理而不是实际代码)。

4

2 回答 2

8

列表推导是各种形式的,和的语法糖。如果您的递归函数可以用这些来描述,那么您可以将其重写为列表推导式。它们不能像上面那样短路,也不能通过累积状态。mapfilter,concatMap

replaceFirst似乎需要一个累加器来“告诉”列表中后面的元素关于早期元素的外观。我认为这使得仅使用列表理解语法编写变得困难或不可能。

于 2013-02-24T20:54:32.610 回答
0

列表理解,灵感来自 leftaroundabout:

replaceFirst elem y xs = [a | let b = break (==y) xs
                                  c = if not (null $ snd b) 
                                         then fst b ++ [elem] ++ tail (snd b) 
                                         else fst b
                              , a <- c]
于 2013-02-25T01:25:55.900 回答