Работа с множествами как функциями

Из курса FP:

type Set = Int => Boolean  // Predicate

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

Почему это имеет смысл?

assert(contains(x => true, 100))

По сути, он передает значение 100 функции x => true. То есть, мы предоставляем 100, он возвращает true.

Но как это связано с множествами?

Что бы мы ни поставили, оно возвращает true. Где в этом смысл?

Я понимаю, что мы можем предоставить нашу собственную реализацию/функцию набора в качестве параметра, который будет представлять тот факт, что предоставленное значение находится внутри набора (или нет) - тогда (только) эта реализация делает функцию contains заполненной некоторым смыслом/значением/ логика/функциональность.

Но пока это выглядит как бессмысленная функция. Он называется contains, но это имя не отражает логики. Мы могли бы назвать его apply(), потому что он применяет функцию (1-й аргумент) к значению (2-й аргумент). Наличие только имени contains может сказать читателю то, что хотел бы сказать автор. Не слишком ли это абстрактно?


person ses    schedule 25.09.2013    source источник
comment
Попробуйте думать о x => true как о наборе всех целых чисел :) Кроме того, помните, что определяемый здесь тип Set больше предназначен для учебных целей, а не для производственного кода.   -  person Shadowlands    schedule 25.09.2013
comment
Я пытаюсь .. :) Интересно, что чем больше scala я использую, тем больше математических вещей я вызываю. Может быть, это не так уж и плохо. weknowmemes.com/wp- контент/загрузки/2012/02/   -  person ses    schedule 26.09.2013


Ответы (2)


Во фрагменте кода, показанном выше, любой набор S представлен так называемой его характеристической функцией, т. е. функцией, которая по некоторому целому числу i проверяет, содержится ли i в набор S или нет. Таким образом, вы можете думать о такой характеристической функции f как о наборе, а именно

{i | все целые числа i, для которых f i равно true}

Если вы считаете любую функцию с типом Int => Boolean набором (на что указывает синоним типа Set = Int => Boolean), то вы можете описать contains как

Учитывая набор f и целое число i, contains(f, i) проверяет, является ли i элементом f или нет.

Некоторые наборы примеров могут сделать идею более очевидной:

Set                                Characeristic Function
 empty set                          x => false
 universal set                      x => true
 set of odd numbers                 x => x % 2 == 1
 set of even numbers                x => x % 2 == 0
 set of numbeers smaller than 10    x => x < 10

Пример. Набор {1, 2, 3} может быть представлен

val S: Set = (x => 0 <= x && x <= 3)

Если вы хотите узнать, есть ли в этом наборе какое-то число n, вы можете сделать

contains(S, n)

но, конечно (как вы уже сами заметили), вы получите тот же результат, если сделаете это напрямую.

S(n)

Хотя это короче, первое, возможно, легче читать (поскольку намерение несколько очевидно).

person chris    schedule 25.09.2013
comment
Это полезно. Все это для меня еще один альтернативный тип абстракции. Например, наличие Int=›Boolean вида «интерфейса»/абстракции для всех функций, которые будут иметь аналогичный «контракт». На данный момент следует иметь в виду только одну вещь: тогда, имея тест assert(contains(x =› true, 100)), недостаточно сказать, что это фактически проверяет функцию contains. Что мне нужно проверить, так это то, что contains(). И то, что я подсознательно хочу сделать, это переименовать «Set» во что-то вроде «SetFunction» или IsContainFunction.. - person ses; 25.09.2013
comment
... или что-то еще, чтобы знать, что на самом деле это не набор, а функция, которая предоставляет мне информацию о том, что находится внутри некоторого гипотетического набора, если он существует в реальности. - person ses; 25.09.2013

Множества (как математически, так и в контексте компьютерного представления) могут быть представлены различными способами. Использование характеристических функций является одной из возможностей. Идея состоит в том, что подмножество S данного универсального множества U полностью определяется функцией f:U-->{true,false} (называемой характеристической функцией подмножества). просто потому, что вы можете рассматривать f(u) как ответ на вопрос «является ли u элементом в S?».

Любой конкретный выбор представления наборов имеет преимущества и недостатки по сравнению с другими методами. В частности, некоторые представления лучше подходят для моделирования на функциональном языке, чем на императивном. Если мы сравним управление множествами как характеристическими функциями и как (отсортированными или несортированными) списками (или массивами), то, например, создание объединений, пересечений и разностей множеств очень эффективно с характеристическими функциями, но не так эффективно со списками. Проверить существование элемента так же просто, как вычислить f(-) с характеристическими функциями, в отличие от поиска в списке. Тем не менее, распечатка элементов в наборе выполняется немедленно со списком, но может потребовать большого количества вычислений с характеристической функцией.

При этом принципиальное отличие состоит в том, что с помощью характеристических функций можно моделировать бесконечные множества, а с массивом это невозможно. Конечно, никакой набор на самом деле не будет бесконечным, но такой набор, как (x: BigInt) x => (x % 2) == 0, действительно представляет этот набор всех четных целых чисел, и с ним действительно можно выполнять вычисления (пока вы не пытайтесь напечатать все элементы).

Итак, у каждого представления есть плюсы и минусы (дух).

person Ittay Weiss    schedule 25.09.2013
comment
математический. Это оно. Вот почему, вероятно, у меня есть намерение переименовать «Set» во что-то вроде «SetFunction» или «IsContainFunction», чтобы показать, что это на самом деле функция, а не набор. Потому что каждый раз, когда я вижу «Сет», я склонен думать, что это настоящий Сет, в котором есть какие-то ценности, которые я могу видеть и чувствовать. - person ses; 25.09.2013
comment
Я думаю, что аргумент заключается в том, что функция является таким же «настоящим» множеством, как и набор элементов, который вы считаете реальным. Кроме того, вы можете найти en.wikipedia.org/wiki/Axiom_of_choice интересное чтение. - person The Archetypal Paul; 25.09.2013
comment
@ses, вам нужно провести различие между тем, как вы думаете о концепции (т. Е. Чем она на самом деле является (какой бы реальной она ни была)) и тем, как эта концепция моделируется. Вы, кажется, думаете о наборе как о сумке с вещами в ней. Для вас может быть наиболее естественным смоделировать его как массив. Массив будет представлением набора real. Но обратите внимание, что представление его как характеристической функции меняет только представление. Им моделируется то же идеальное понятие множества. Вот почему вы называете тип данных Set (не SetFunction) и Contain (не ContainFunction). Для пользователя это набор. - person Ittay Weiss; 26.09.2013