1

これが末尾再帰を表しているかどうかを知りたいです。そうでない場合は、どうすればできますか。

 countP :: [a] -> (a->Bool) -> Int
 countP [] _ = 0
 countP (x:xs) p = countP_aux (x:xs) p 0

 countP_aux [] _ _ = 0
 countP_aux (x:xs) p acumul
                        |p x==True = (countP_aux xs p (acumul))+1
                        |otherwise = (countP_aux xs p (acumul))

  countP [1,2,3] (>0)
  3
  (72 reductions, 95 cells)

この演習では、p 条件によって検証されるリスト内の値の数を示します。ありがとう

4

1 に答える 1

4

これは末尾再帰ではありません。

(countP_aux xs p (acumul))+1

末尾呼び出しは、再帰呼び出しの結果で計算を行うのではなく、再帰呼び出しの結果を返す必要があります。

追加の作業を実行するアキュムレータを使用することで、非末尾再帰関数を末尾再帰関数に変換できます。

単純なカウント関数があるとします

f a
  | a < 1 = 0 
  | otherwise = f (a-1) + 1

次のように末尾再帰にすることができます。

f' acc a = 
  | a < 1 = acc 
  | otherwise = f' (acc + 1) (a-1)
f = f' 0
于 2013-01-16T11:29:31.127 に答える