2016-04-05 25 views
-3

構文に関するヘルプが必要です。関数を返す関数の再帰呼び出し

質問:この状況でメソッドを再帰的に呼び出すにはどうすればよいですか?

以下のコードでエラー見つけてください:ここでは

def increase[T: Numeric](x: T) = (y: T) => { 
    require(implicitly[Numeric[T]].gt(x , 0.asInstanceOf[T])) 
    if (implicitly[Numeric[T]].gt(y , 0.asInstanceOf[T])) 
     implicitly[Numeric[T]].plus(x, y) 
    else     
     increase[T](x)(implicitly[Numeric[T]].abs(y)) 
} 

val inc = increase[Int] _ 

println(inc(5)(-1)) 

はエラーコードです: C:ソース\> CDのスカラ

C:\ソース\スカーラ>スカラmain.scala C :ソース\ \スカラ\ main.scala:29:エラー:再帰的方法増加ニーズがTYをもたらす PE increaseT(暗黙[数値[T] ABS(Y)) ^ つのエラーは

見出さ

c:¥Sources¥scala>

+0

[スカラークラスのエラー:再帰的メソッドprintExprには結果の型が必要]の可能な複製(http://stackoverflow.com/questions/13260275/error-on-scala-class-recursive-method-printexpr-needs-result-type ) – Ben

+0

他にも、画像としてではなく、テキストとしてのエラーを投稿してください。 – Ben

+0

関数から関数を返すので、関数の署名を変更することをお勧めしますか。 – Pavel

答えて

4

関数定義にはかなりの問題があります。コンテキストがdef increase[T](x: T)(implicit ev: Numeric[T])(y: T)のようなものとしての仕事、def increase[T: Numeric](x: T) = (y: T) => ???行為を境界とどのように

  1. 。暗黙的な引数リストは普通のものの間にあるので、xyの両方を次々と提供することはできません。したがって、increase(x)(abs(y))は機能しません。increase(x).apply(abs(y))のようなものを使用する必要があります。

  2. 0.asInstanceOf[T]を使用しないでください。たとえば、TBigIntの場合、これは0.asInstanceOf[BigInt]になり、実行時例外:java.lang.ClassCastException: java.lang.Integer cannot be cast to scala.math.BigIntが発生します。代わりにimplicitly[Numeric[T]].zeroを使用できます。

  3. これらをすべてのところに置いておけば、あまり美しくはありません。この暗黙的な引数の名前を固定し、暗黙的な操作をインポートする方が良いので、x > num.zerox + yを使用することができます。以下の例を参照してください。

  4. コメントで説明したように、再帰関数の戻り値の型を明示的に指定する必要があります。あなたの場合、それはT => Tでなければなりません。

    def increase[T](x: T)(y: T)(implicit num: Numeric[T]): T = { 
        import num._ 
    
        require(x > num.zero) 
        if (y > num.zero) x + y 
        else increase(x)(y.abs) 
    } 
    
    :また

    def increase[T](x: T)(implicit num: Numeric[T]): T => T = (y: T) => { 
        import num._ 
    
        require(x > num.zero) 
        if (y > num.zero) x + y 
        else increase(x).apply(y.abs) 
    } 
    
    val inc = increase[Int] _ 
    
    println(inc(5)(-1)) 
    

    は、あなたが匿名関数を使用せずに同様の定義を持つことができます。

だから、すべてこれであなたは増加の方法については、次の定義を持つことができます

ちょうどその場合、再帰的にする必要はありません。

def increase[T](x: T)(y: T)(implicit num: Numeric[T]): T = { 
    import num._ 

    require(x > num.zero) 
    x + y.abs 
} 
+0

さて、わかりました。これは私のための良いと詳細な答えのように見えます。いくつかの分野でスカラー知識を向上させる必要があるように見えます。ありがとう! – Pavel

+0

これを確認するには、T => T =(y:T)ここで関数の戻り値の型を定義します。私は矢印の後の部分とちょっと混乱しています。それはどのような構造ですか?ありがとう – Pavel

+1

@PavelOliynyk 'T => T 'が戻り値の型である場合、' = 'を持つと、関数定義が開始します:'(y:T) '。あなたのコードのように、 'T => T '型定義が追加されています。そして、 'A => B'は関数の型で、' A'型の引数をとり、 'B'型の結果を返します。 'A => B'は実際に' Function1 [A、B] 'の構文的な砂糖です。 – Kolmar