2

我怎样才能做一个函数(递归),用参数 b(1) 代替列表上的参数 a(0)?例如:

    substitute 0 1 [1,0,3,0,4,0,0]
    [1,1,3,1,4,1,1]

谢谢。

4

2 回答 2

6

不需要递归!

substitute :: Eq a => a -> a -> [a] -> [a]
substitute old new = map subs where
    subs x | x == old  = new
           | otherwise = x

如果这是家庭作业,您可以轻松地替换(递归)的定义。map

于 2012-11-04T15:01:40.870 回答
5

最简单的是使用列表推导:

subst a b xs = [c | x<-xs, let c=if x==a then b else x].

但这不是递归。使用递归,只是对列表结构(即结构递归)的案例分析:

subst a b [] = []
subst a b (x:xs) 
   | x==a      = b:subst a b xs
   | otherwise = x:subst a b xs

这是foldr(or map) 模式的一个实例:

subst a b = foldr (\x xs-> (if x==a then b else x) : xs) [] 
subst a b = map   (\x   ->  if x==a then b else x      ) 

通常建议在递归定义中使用“worker”函数,如下所示:

subst a b xs = go xs
  where
    go [] = []
    go (x:xs) 
       | x==a      = b:go xs
       | otherwise = x:go xs

但如果你凝视它片刻,你就会发现它是遵循map模式的。在 Haskell 中,递归模式由高阶函数捕获,例如mapfilter

于 2012-11-04T15:30:32.430 回答