Haskell 使用列表理解代替递归

Haskell 使用列表理解代替递归,haskell,Haskell,对于下面的例子,我很好奇是否可以使用列表理解来代替递归 函数replaceFirst,它接收一个元素和一个列表,并替换列表中第一个出现的元素 这可以使用递归实现,如下所示: replaceFirst _ [] = [] replaceFirst elem y (x:xs) | x==y = (elem:xs) | otherwise = x:replaceFirst elem y xs 我的问题是,这个递归函数,或者在列表中元素第一次出现时

对于下面的例子,我很好奇是否可以使用列表理解来代替递归

函数
replaceFirst
,它接收一个元素和一个列表,并替换列表中第一个出现的元素

这可以使用递归实现,如下所示:

replaceFirst _ [] = []
replaceFirst elem y (x:xs) | x==y = (elem:xs)
                           | otherwise = x:replaceFirst elem y xs
我的问题是,这个递归函数,或者在列表中元素第一次出现时操作的类似递归函数,是否可以替换为列表理解函数?为什么?(我更关心的是推理,而不是实际代码)。

列表理解适用于各种形式的
map
过滤器、
concatMap
。如果您的递归函数可以用这些描述,那么您可以将其重写为列表。它们不能短路,就像上面所说的,也不能通过累积状态


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

列表理解,受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]
replaceFirst elem y xs=[a | let b=break==y)xs
c=如果不是(空$snd b)
然后fst b++[elem]++tail(snd b)
其他fst b

,a,这不是重复的吗?删除和替换之间的差别不是很大,也不会影响是否可以使用列表递归来完成。第一个等式缺少一个模式。这可能有助于将列表理解看作是
foreach
循环,您可以在其中对每个元素应用过滤器和计算。请参阅
do
list monad在这个wiki+1中的语法,谢谢你的回复。我很难确定是否可以单独使用list comp来完成,但你的回答只是澄清并证实了我的第一直觉。谢谢!@MiGusta:是的,当然这并不意味着该函数不能用其他标准的更高阶重写r函数。
replaceFirst elem y xs |(l,uu:r)