2017-10-22 9 views
1

私はRの宣言型プログラミングのパラダイムを実験しています。nからmまでの整数列を合計する関数を定義しました。私はsum()機能を使用すると期待された結果を返します:再帰R関数で "+"が失敗するところで "Sum()"が成功するのはなぜですか?

> sumRange <- function(n, m) if (n <= m) return(sum(n, sumRange((n+1), m))) 
> sumRange(1, 10) 
[1] 55 

をしかし、私は関数がnumeric(0)を返し+演算子を使用する場合:

> sumRange <- function(n, m) if (n <= m) return(n + sumRange((n+1), m)) 
> sumRange(1, 10) 
numeric(0) 

をなぜオペレータ+は、この再帰関数では動作しませんか?関数を書き直す方法はありますか?

答えて

1

問題は、else条件を指定しないことです。したがって、再帰の最後に、if条件が失敗したときにRがNULLを返しているように見えます。これは、本質的に、あなたの再帰のための基本ケースを定義していることを

sumRange <- function(n, m) return(ifelse (n <= m, (n + sumRange((n+1), m)), 0)) 
sumRange(1, 10) 
[1] 55 

注:他の条件として0を返すことはあなたの問題を修正します。ヒットすると、ベース・ケースは再帰を終了し、スタック上のコールを解放します。明示的にあなたの関数を書いてみてください、あなたのコードを言葉で表現方法で問題を表示するには

sumRange <- function(n, m) { 
    if (n <= m) { 
     return(n + sumRange((n+1), m)) 
    } 
    // but what gets returned if n > m ? 
    // this is undefined behavior 
} 

私はRの第一人者ないんだけど、私の理解は、Rは、Cで書かれたことで、 Cはelseの条件でこのような再帰を許可するかもしれません。しかし、その行動は明確に定義されておらず、あなたはそれに頼るべきではありません。

Demo

+0

+1ベースケース。 R関数は、返り値が利用できない場合、 'NULL'オブジェクトを返すように見えます。だから、よく定義されているかもしれませんか? – Suren

+0

@Headpoint単語の選択。 Rがデフォルトで返すものにかかわらず、OPは基本ケースを決して決して決してしなかったので、再帰の重要な部分は最も確かに定義されていません。 Rでコーディングするときにこの動作に頼るべきではありません –

1

(明示的または暗黙的なreturnステートメントを使用して)ノーリターンが実行されていないが存在する場合、R関数がNULLオブジェクトを返すように思われます。

このオブジェクトに数値を追加すると、単にnumeric(0)が返されます。

したがって、2番目のケースでは、nが11に達すると、NULLオブジェクトが返され、値が追加されます。しかし、NULL + 10 + 9 .. = numeric(0)。最初の関数が実行されると

no_ret <- function() 
{ 
# just return nothing 
} 

obj <- no_ret() 
obj 
# NULL 
class(obj) 
# "NULL 
new_obj <- obj + 10 
new_obj 
# numeric(0) 

チェックこれは、どのような和文が取得すると、その中NULLと ベクトルです。たとえば、実際にvec <- c(10, 9, ...)である vec <- c(NULL, 10, 9,...)のように、期待される結果が得られます。

> c(NULL, 10:1) 
[1] 10 9 8 7 6 5 4 3 2 1 
> sum(NULL, 10:1) 
[1] 55 

> NULL + 10:1 
integer(0) 
+0

私はこれを "もしreturn文が実行されなければ、..."と考えました。私はあなたがすでにそうしていると思って、それ以上のことを書いていたと思います。 – Suren

関連する問題