37

私は以下のコードを理解しようとしています:


ここでは、新しい型エイリアス Set が宣言されています。これは、Int パラメーターを取り、ブール値を返す関数です。

type Set = Int => Boolean

ここでは、新しいメソッド「contains」が宣言されています。このメソッドは、ブール値を返す Set および Int 型の 2 つのパラメーターを受け取ります。ブール値は、以前に宣言された関数に設定されます ('type Set = Int => Boolean')。しかし、Int 'elem' が Set 's' のメンバーであるかどうかを判断するために実行されるロジックは何ですか?

def contains(set: Set, elem: Int): Boolean = set(elem)

ここでは、関数を返すセットを返すメソッドが定義されていますか?

def singletonSet(elem: Int): Set = set => set == elem

コメント付きの完全なコード:

  /**
   * We represent a set by its characteristic function, i.e.
   * its `contains` predicate.
   */
  type Set = Int => Boolean

      /**
       * Indicates whether a set contains a given element.
       */
def contains(set: Set, elem: Int): Boolean = set(elem)

      /**
       * Returns the set of the one given element.
       */
      def singletonSet(elem: Int): Set = set => set == elem
4

4 に答える 4

99

論理的な順序で、逆方向に読んでみましょう。

0, 1, 2, 3, 5, 8たとえば、整数の有限集合があるとします。

この整数のセットを記述する 1 つの方法は、整数ごとに、整数がセット内にある場合は true を返し、そうでない場合は false を返す関数 (その特性関数またはインジケーター関数) を使用することです。この関数の署名は、説明したように、常にInt => Boolean(「整数を教えてください。セット内にあるかどうかを教えてくれます」) にする必要がありますが、その実装は特定のセットによって異なります。

上記の例のセットでは、この関数を次のように簡単に記述できます。

val mySet: Int => Boolean = x => Array(0,1,2,3,5,8) contains x

または、セット内の int がフィボナッチ数列の最初のものであることを認識し、少し洗練された方法で f を定義します (ここでは行いません...)。私が使用した「contains」は、すべての scala コレクションに対して定義されていることに注意してください。いずれにせよ、セットに何があり、何がそうでないかを示す関数ができました。REPLで試してみましょう。

scala> val mySet: Int => Boolean = x => Array(0,1,2,3,5,8) contains x
mySet: Int => Boolean = <function1>

scala> mySet(3)
res0: Boolean = true

scala> mySet(9)
res1: Boolean = false

mySet には typeInt => Booleanがあり、これを型エイリアスとして定義すると読みやすくなります。

scala> type Set = Int => Boolean
defined type alias Set

Set読みやすさに加えて、のエイリアスとして定義することで、ある意味で Setその特徴的な機能Int => Booleanであることを明示できます。型エイリアスを使用して、より簡潔な (ただしそれ以外は同等の) 方法で mySet を再定義できます。Set

scala> val mySet: Set = x => Array(0,1,2,3,5,8) contains x
mySet: Int => Boolean = <function1>

この長い回答の最後の部分です。このシングルトン セットを記述する特性関数を定義しましょう: 3. 簡単:

val Singleton3 : Set = set => set == 3

4 つだけを含むシングルトン セットの場合、次のようになります。

val Singleton4 : Set = set => set == 4

したがって、これらの関数の作成を一般化して、任意の整数に対して、その整数のみを含むセットを記述するシングルトン関数を返すメソッドを記述しましょう。

def singletonSet(elem: Int): Set = set => set == elem

付録:

実際には必要ないので、この部分はスキップしました。def contains(set: Set, elem: Int): Boolean = set(elem)

私はそれは一種の無意味だと思いますし、(これ以上のコンテキストがなければ) scala の他の型と同じように、関数を引数として渡す方法を示すための不自然な例のように見えます。関数とを取り、Int => Bool関数をIntに適用するだけなIntので、次のことができます

scala> contains(mySet, 3)
res2: Boolean = true

mySet(3)これは、直接電話をかけるようなものです。

于 2012-10-24T16:26:44.073 に答える
5

「カリー化」に関する講義ビデオを見た後、パオロの解決策をより詳細に表現すると、次のようになると思います。

    def singletonSet(elem: Int): Set = {
    def innerFunction (givenElement: Int) = 
      if (elem == givenElement) true
      else false
      innerFunction
  }

間違っていたら訂正してください!

于 2013-10-04T05:18:24.900 に答える
2

あなたの質問に答えるには -しかし、Int 'elem' が Set 's' のメンバーであるかどうかを判断するために実行されるロジックは何ですか?

これは、実際の関数呼び出しを行うときに実行されます。次の関数呼び出しを検討してください。

含む (singletonSet(1), 1)

現在、singletonSet はdef singletonSet(elem: Int): Set = x => x == elemとして定義されています(わかりやすくするために、識別子 x を使用することにしました)。singletonSet の戻り値の型は、Int 引数を取り、Boolean を返す Set 型の関数です。したがって、上記の呼び出し関数の最初の引数 singletonSet(1) は、関数x => x == 1と同等であり、ここでは elem は 1 です。

含む ((x => x == 1),1)

ここで、contains 関数def contains(f: Set, elem: Int): Boolean = f(elem)の定義を検討します。上記の呼び出しの最初の引数は関数 x => x == 1 で、仮パラメーター f を置換し、2 番目の引数 1 は仮パラメーター elem を置換します。contains の戻り値は、f(1) に相当する関数 f(elem) です。f(x) は (x == 1) として定義されているため、f(1) は (1 == 1) と等しく、true を返します。

同じロジックで行くと、contains(singletonSet(1), 2) のような関数呼び出しは、最終的に (1 == 2) と等しくなり、false を返します。

于 2016-10-06T13:30:14.213 に答える
2

私も今受講していますが、戸惑いもありましたが、今は理解できていると思います。

def singletonSet(elem: Int): Set = (x : Int) => x == elem

ここで、singletonSet はSet 型の関数を返す関数であり、次のように定義されます。type Set = Int => Boolean

def contains(s:Set, elem:Int): Boolean = s(elem)したがって、たとえば次のように呼び出すとcontains(singletonSet(1), 2)、singletonSet(1) は elem (singletonSet の定義内) が 1 に設定された関数を返し、2 (elem としても定義されていますが、contains のパラメーターで定義されています) が渡されます。 x in singletonSet 定義のように、Java セットのアイデアを取り除く必要があります。設定した値を保持するために singletonSet は必要ありません。

理解を深めるために、パラメーター名を次のように変更できます。

def singletonSet(elemToStore: Int): Set = (x : Int) => x == elemToStore

def contains(s: Set, elemToCheck: Int): Boolean = s(elemToCheck)

于 2018-01-09T19:04:15.997 に答える