使用List Comprehension代替递归

时间:2013-02-24 20:40:15

标签: haskell

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

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

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

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

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

2 个答案:

答案 0 :(得分:8)

对于各种形式的mapfilter,concatMap,列表理解为syntactic sugar。如果您的递归函数可以用这些来描述,那么您可以将其重写为列表解析。它们不能像你上面那样短路,也不能通过累积状态。

你的replaceFirst似乎需要一个累加器来“告诉”列表中后面的元素有关早期元素的外观。我认为这很难或不可能只使用列表推导语法编写。

答案 1 :(得分:0)

列表理解,受左撇子启发:

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]