Подтвердить что ты не робот

Является ли мое понимание ниже кода scala правильным?

Я просто пытаюсь понять приведенный ниже код:


Здесь объявлен новый тип alias Set, который является функцией, которая принимает Int параметр и возвращает логическое

type Set = Int => Boolean

Здесь объявлен новый метод 'contains', который принимает два параметра типа Set и Int который возвращает логическое значение. Логическое значение устанавливается в функцию, объявленную ранее ('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
4b9b3361

Ответ 1

Пусть прочитайте вид назад, в логическом порядке.

Скажем, что у вас есть конечный набор целых чисел: 0, 1, 2, 3, 5, 8 например

Одним из способов описания этого набора целых чисел является функция (ее характеристика или функция индикатора), которая для каждого целого возвращает true, если целое число находится в наборе, false, если это не так. Подпись для этой функции, как мы ее описали, всегда должна быть Int => Bool ( "дать мне целое число, я скажу вам, если оно в наборе" ), в то время как его реализация будет зависеть от конкретного набора.

Для набора в моем примере выше вы можете написать эту функцию просто как:

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

или признать, что ints в наборе являются первыми из последовательности Фибоначчи и определяют 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 имеет тип Int => Boolean, который мы можем сделать более читаемым, если мы определим его как псевдоним типа.

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

Помимо читаемости, определение Set в качестве псевдонима Int => Boolean делает его явным, так что Set является его характеристической функцией. Мы можем переопределить 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

для набора Singleton, содержащего только 4, это будет:

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

Итак, позвольте обобщить создание этих функций и написать метод, который возвращает функцию Singleton, которая для любого целого описывает набор, содержащий только это целое число:

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).

Ответ 2

После просмотра лекционного видео на "Currying", я считаю, что решение Паоло, выраженное более подробным образом:

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

Plesae поправил меня, если я ошибаюсь!

Ответ 3

Чтобы ответить на ваш вопрос - Но какая логика выполняется, чтобы определить, является ли Int 'elem' членом Set 's'

Это выполняется, когда вы выполняете фактический вызов функции. Рассмотрим следующий вызов функции.

содержит (singletonSet (1), 1)

Теперь singletonSet определяется как def singletonSet (elem: Int): Set = x = > x == elem (я хочу использовать идентификатор x для ясности). Возвращаемый тип singletonSet - это функция типа Set, которая принимает аргумент Int и возвращает Boolean. Таким образом, первый аргумент функции firsttonSet (1) приравнивается к функции x = > x == 1, так как elem здесь равно 1. Таким образом, мы получаем

содержит ((x = > x == 1), 1)

Теперь с учетом определения содержит функцию def содержит (f: Set, elem: Int): Boolean = f (elem). Первым аргументом в вызове выше является функция x = > x == 1, которая заменяет формальный параметр f, а второй аргумент 1 заменяет формальный параметр elem. Возвращаемое значение содержит функцию f (elem), которая равна f (1). Поскольку f (x) определяется как (x == 1), f (1) приравнивается к (1 == 1), который возвращает true.

Идя по той же логике, вызов функции, такой как contains (singletonSet (1), 2), окончательно будет равен (1 == 2), который вернет false.