2

リストの引数a(0)を引数b(1)に置き換える関数を(再帰的に)実行するにはどうすればよいですか?例えば:

    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(または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      ) 

通常、次のように再帰的定義で「ワーカー」関数を使用することをお勧めします。

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

しかし、少しの間それを見つめると、それがmapパターンに従っていることがわかります。mapHaskellでは、再帰パターンは、filterなどの高階関数によってキャプチャされます。

于 2012-11-04T15:30:32.430 に答える