Как стать автором
Обновить

Комментарии 13

Да-да, от перестановки слагаемых (множителей) сумма (произведение) не меняется, все мы имели дело с Васиными и Петиными апельсинами ассоциативными бинарными операциями ещё в начальной школе.

Что-то вы уже в самом начале напутали. Ассоциативность - это не про порядок аргументов, это про порядок выполнения цепочки операций вида x ? y ? z ? ... Для ассоциативных операций (x ? y) ? z = x ? (y ? z). Порядок аргументов (перестановка мест слагаемых) - это коммутативность.

Собственно, пример с контактенацией строк это показывает. Результат конкатенации зависит от порядка аргументов (операция не коммутативна), но не зависит от порядка выполнения конкатенаций в цепочке (операция ассоциативна).

Да, вы совершенно правы, спасибо.

Формальное определение и математическая формула, всё же, корректны. Пример, да, может вызывать споры, но моя цель была максимально упростить понимание для новичков. Если взяли Петины апельсины, сложили с Мишиными, а потом с Танечкиными, то их количество будет таким же, как если сложить сначала Танечкины и Петины апельсины, а потом к ним прибавить Мишины. Но по сути, это "от перестановки слагаемых сумма не меняется".

В математике сложение одновременно и ассоциативно (можно расставлять скобки как угодно), и коммутативно (можно менять порядок аргументов местами). Конкатенация только ассоциативна. Поэтому отсылка к перестановке слагаемых для полугруп, по сути, мимо кассы и новичков может лишь сбивать с толку.

В JavaScript есть врождённый порок - здесь "+" используется и как оператор сложения, когда речь идёт о числах, и как оператор конкатенации, когда речь идёт о строках. fp-ts в некоторой степени это исправляет, вводя разные имена для оператора конкатенации (Semigroup.concat) и сложения (Semiring.add).

Ассоциативность можно наглядно показать на примере строк:

concat ("foo", concat ("bar", "baz")) ==

cancat (concat ("foo", "bar"), "baz") ==

"foobarbaz"

Но если переставить аргументы местами, то результат будет другим.

Пример может и правильный, но фраза совсем некорректная. Перестановка слагаемых - это не ассоциативность, а коммутативность, не стоит путать людей.

Формальное определение и математическая формула, всё же, корректны.

Операция ассоциативна, когда результат не зависит от расстановки скобок, и только. А в формуле выше ещё и элементы переставляются. Сейчас она выглядит как (a * b) * c = (a * c) * b. Похоже, просто опечатку пропустили, https://ru.wikipedia.org/wiki/Ассоциативность_(математика).

Но по сути, это "от перестановки слагаемых сумма не меняется".

Главное, не складывать числа с плавающей точкой)

Математическая формула не корректна. У Вас написано (ab)c = (ac)b, а должно быть (ab)c = a(bc).

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

Мог бы кто-нибудь объяснить, откуда это следует? Ассоциативная бинарная операция в полугруппах уже имеется. Что мешает применить ее несколько раз?

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

Хотя да, технически никто не запрещает взять первый попавшийся элемент множества в качестве начального, и комбинировать с ним остальные. Но такой подход не даёт ответа для пустого множества.

Почему не даёт? Можно для пустого множества задать произвольный элемент. Другое дело, что это не позволит гомоморфизм между свободным моноидом списков и полугруппой установить. Но гомоморфность не всегда нужна.

Возможно, речь идет об удобстве работы с ts. Не знаю ts, но моноиды от полугруппы по определению отличаются только нейтральным элементом. И в той, и в другой структуре задана именно бинарная операция, которая по определению всегда требует два аргумента.

моноиды дают возможность легко объединять множество элементов в один.

Скорее имелось ввиду, что модуль Monoid предоставляет утилиту concatAll(), которая делает сверку последовательности моноидов. Аналогичная функция есть и в модуле Semigroup, но требует дополнительный аргумент с начальным значением на случай если последовательность окажется пустой (Monoid в таком случае использует empty).

В определении нейтрального элемента не хватает свойства перестановочности, если x - нейтральный, то x * a = a * x = a. Сейчас у нас элемент x является только правым нейтральным, https://ru.wikipedia.org/wiki/Нейтральный_элемент#Определение. Операция в полугруппе и моноиде не является коммутативной.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий