5

私はscalaが初めてで、指定された整数が奇数かどうかをチェックする関数リテラルを書き込もうとしています。私の最初の試みは:

val isOdd = (x:Int) => (x & 1) == 1

それはうまく機能し、パラメーター x はこの関数リテラル内で 1 回しか現れないため、次のように "_" 表記を使用してさらに単純化したくなります。

val isOdd = ((_:Int) & 1 ) == 1

ただし、今回はコンパイラが不平を言います:

警告: `==' を使用して新しいオブジェクトを比較すると、常に false が返されます
val isOdd = ((_:Int) & 1 ) == 1

この警告はどういう意味ですか? ((_ :Int) & 1)コンパイラは、値が得られるビットごとの操作ではなく、新しいオブジェクトとして認識するのはなぜですか? 「_」表記を使用してこの関数リテラルを記述する方法はありますか?

4

5 に答える 5

20

問題は基本的に、Scalaが違いを伝える必要があるということです

val isOdd = ((_:Int) & 1 ) == 1

等号の右側のすべてをラムダにしたい場合、および

val result = collection.map( _ + 1 )

かっこ内のものだけをラムダにしたい場合

Scalaは、アンダースコアを使用してラムダを作成するときに、そのラムダの境界として最も内側の括弧のセットを選択することを決定しました。例外が1つあります。その目的は、タイプ宣言をプレースホルダー(_:Int)とグループ化することだけであるため、最も内側の括弧としてカウントされません。_

したがって:

val isOdd = ((_:Int) & 1 ) == 1
            ^^^^^^^^^^^^^^
            this is the lambda

val result = collection.map( _ + 1 )
                            ^^^^^^^
                            this is the lambda

val result = collection.map(( _ + 1) / 2)
                            ^^^^^^^^
                            this is the lambda
                            and the compiler can't infer the type of the _

val result = somemap.map(( _ + 1) / 2 * _)
                         ^^^^^^^^
                         this is an inner lambda with one parameter
                         and the compiler can't infer the type of the _
                         ^^^^^^^^^^^^^^^^^
                         this is an outer lambda with one parameter

この最後のケースでは、次のようなことができます

_.map(_ + 1)

そしてそれを翻訳してもらいます

x => x.map( y=> y + 1 )
于 2011-01-18T15:14:34.247 に答える
10

ほんの少しの不正行為:

val isOdd = (_: Int) % 2 == 1

:-)

于 2011-01-18T20:30:07.860 に答える
7

そこに行きます:

val isOdd = ((_: Int) & 1) andThen (1 ==)
于 2011-01-18T16:36:01.220 に答える
2

Scala が行っていることは次のとおりです。

  • ((_:Int) & 1 )type のオブジェクト(Int) => Int、つまり関数を見て作成します。
  • 次に、比較演算子==を適用して、この関数を値 1 と比較します。

関数は値 1 と等しくありません。したがって、結果はfalseであるため、コードは次のようになります。

val isOdd = false

あなたができることは== 1、計算の一部を行う別の無名関数を作成することです。これは醜いです:

val isOdd = ((_: Int) & 1)(_: Int) == 1

これは、より冗長な (そしておそらく理解しやすい) と同等です。

val isOdd = (x: Int) => 1 == ((_: Int) & 1)(x)
于 2011-01-18T15:02:30.070 に答える
1

別のアプローチ

val isOdd = (_:Int).&(1) == 1
于 2012-01-06T18:47:23.370 に答える