0

次のコードがあります。これは、配列を検索し、何かが 2 番目の引数一致するかどうかを確認することになっています。

def any(check: Set[Any], expr: Boolean): Boolean = {
  var checked = check.filter(_ => expr)
  if (checked == Set())
    return false
  else
    return true
}

次のように呼び出されることになっています。 any(Set(3, 4, 5, 6), _ > 5)

しかし、私がそれを呼び出すとき:

error: missing parameter type for expanded function ((x$1) => x$1.$greater(5))

私は関数型言語と Scala の経験がほとんどないので、何が起こっているのか、どのように修正するのかを徹底的に説明してください!

4

4 に答える 4

6

この問題は、式を評価するときの1つです。あなたの電話で

check.filter(_ => expr)

渡された式の値でフィルタリングcheckしています。ただし、呼び出しでは、ブール値ではなく関数を渡しています。

あなたがやろうとしていることは、私が思うに、関数を渡し、それをあなたのcheck呼び出しで評価することです。例えば:

def any[T](check: Set[T], test: T => Boolean): Boolean = {
  var checked = check.filter(test)
  if (checked == Set())
    return false
  else
    return true
}

これで、これを次のように呼び出すことができます。

any(Set(3, 4, 5, 6), (_:Int) > 5)
于 2012-07-13T03:22:15.870 に答える
4

このコードには、Scala に関するいくつかの誤解があります。最初に対処する必要があるのは次のとおりです。

def any(check: Set[Any], expr: Boolean): Boolean = {
  var checked = check.filter(_ => expr)
  if (checked == Set())
    return false
  else
    return true
}

any(Set(3, 4, 5, 6), _ > 5)

まず、exprですBoolean。ABooleanはどちらかtrueまたはfalse-- それ以外にはなり得ません。一方、exprは「式」に由来します。これは、評価する必要がある式と考えられます。したがって、exprBooleanが一致する可能性は低いため、概念上の問題が進行中であることを示す最初の手がかりです。

ここで、パラメーター_ > 5として渡しますが、どちらでもありません。は true になりますが、false になりますが、は関数であり、関数は ではありません 。expr_ > 5truefalse10 > 53 > 5_ > 5Boolean

アンダースコアを考えてみましょう..._ > 5は を意味し(x) => x > 5ます。_ > _などを意味(x, y) => x > yします。アンダースコアをよく理解していない場合は、使用しないでください。代わりに完全な構文を使用してください。後で理解できるようになるので、学習を遅らせる必要はありません。

ここで、他の概念的な問題のためにそれを取り上げます。これは次のとおりです。

_ => expr

z => exprこれは、受け取ったパラメータを完全に無視する関数とほぼ同等です。ここでのアンダースコアの意味は上記とは異なることに注意してください。実際、この回答では、アンダースコアの 11 の異なる意味を数えたことがあります。アンダースコアを理解するまでアンダースコアの使用を避けるもう 1 つの理由。

したがって、コードの問題は次のとおりです。

  1. Booleanあなたが望んでいたところに を受け取っていますFunction1[Any, Boolean]
  2. フィルタリングする必要があるかどうかを計算するときに、フィルタリングされている要素を無視しています(1のためにコンパイルされた唯一の構文であるためだと思います)。
  3. 期待される場所に関数を渡していますBoolean

_ > 6は有効なFunction1[Any, Boolean]ではなく、Anyは を実装していないため、1 と 2 を修正してもコードは機能しません>

あなたは動的言語のバックグラウンドAnyを持っているのではないかと思います。あなたが扱っているもののタイプを伝える必要がないための簡単な「フォールバック」として使用します。やらないでください - を使っAnyても物事が簡単になるわけではなく、物事が難しくなります。

そのメソッドを正しく記述する方法を示す他の2つの回答があります。詳細はそれらに任せます。私は一般的な問題に対処したかっただけで、将来そのような問題を回避するためにあなたを導くことができないかどうかを確認したかった.

于 2012-07-13T16:08:22.480 に答える
4
Set(3, 4, 5, 6).exists(_ > 5)
于 2012-07-13T03:07:22.873 に答える
3

@RayToalsの回答に加えて:

複数のパラメーター リストを作成する場合は、Scala の型推論を使用できます。

def any[T](check: Set[T])(test: T => Boolean): Boolean = {
  val checked = check.filter(test)
  checked.nonEmpty
}

scala> any(Set(3,4,5,6))(_>5)
res6: Boolean = true

scala> any(Set(3,4,5,6))(_>6)
res7: Boolean = false

注: return ステートメントを使用しないでください (特に、明示的に true と false を返さないでください) - ほとんどの場合、return ステートメントは必要ありません。さらに、avarが必要かどうかはっきりしない場合は、a を使用しないでください。最後に、メソッド全体を 1 つの式で記述することができます。

def any[T](check: Set[T])(test: T => Boolean): Boolean =
  check.filter(test).nonEmpty
于 2012-07-13T07:58:48.323 に答える