Информация об изменениях

Сообщение Re[2]: Моноид и компаратор от 08.06.2020 15:47

Изменено 08.06.2020 15:50 Qbit86

Re[2]: Моноид и компаратор
Здравствуйте, Sinclair, Вы писали:

S>0. 90% из того, о чём он рассуждает — это сложный способ разрешить определять operator+ за пределами типа.

S>В плюсах этой проблемы нет как класса благодаря наличию свободных функций; в шарпе этого нет — в итоге имеем печальный итог: мы не можем описать оператор+ для аргументов типа A и B, не будучи авторами A или B.

Проблема определить оператор сложения вне типа никак и ничем принципиально не отличается от проблемы определить оператор сравнения вне типа. Это ровно та же проблема для ровно тех же задач — написание обобщённых алгоритмов и структур данных, которые используют полиморфные сложения и сравнения.

Алгоритмы, использующие обобщённое сравнение всем известны: сортировки, деревья, хэш-таблицы. Использование компаратора ни у кого удивления не вызывает.
Алгоритмы, использующие обобщённое сложение никому кроме меня не известны: например, алгоритм Дейкстры на графах. Поэтому использование моноида вызывает бурю эмоций.

Для обобщённого сравнения ты реализуешь IComparer<T> или IEqualityComparer<T>. Аналогично, для обобщённого сложения (обобщённой бинарной операции) ты реализуешь IMonoid<T>. Или, если ты больше не инженер, а уже менеджер, то IGenericAggregationControllerManager<T>, так трудовому народу понятнее.

S>1. Рассказ про то, что у инта сразу два моноида, был убедителен, но непонятно, как именно это можно применить. Ну, кроме вырожденного случая "давайте проагрегируем массив интов с использованием 1 и * в качестве нашего моноида".


Давай не про инты, а про float'ы, ок? Аддитивный моноид понятно, например, складывать веса дуг вдоль пути на графе. Мультипликативный моноид, например, когда у тебя цепочка процентных ставок: начинаем с 1.0, заплатили налог 13% (домножить на 0.87), получили interest 5% (домножить на 1.05) и так далее.

Взя затея вокруг шейпов — это добавить чуть синтаксического сахара вокруг всех этих IEqualityComparer<T>'ов и IMonoid<T>'ов, чтоб передавать не инстансы (они ж все одинаковые stateless), а сами типы. Примерно, как в этой старой статье: https://github.com/MattWindsor91/roslyn/blob/master/concepts/docs/csconcepts.md
Re[2]: Моноид и компаратор
Здравствуйте, Sinclair, Вы писали:

S>0. 90% из того, о чём он рассуждает — это сложный способ разрешить определять operator+ за пределами типа.

S>В плюсах этой проблемы нет как класса благодаря наличию свободных функций; в шарпе этого нет — в итоге имеем печальный итог: мы не можем описать оператор+ для аргументов типа A и B, не будучи авторами A или B.

Проблема определить оператор сложения вне типа никак и ничем принципиально не отличается от проблемы определить оператор сравнения вне типа. Это ровно та же проблема для ровно тех же задач — написание обобщённых алгоритмов и структур данных, которые используют полиморфные сложения и сравнения.

Алгоритмы, использующие обобщённое сравнение всем известны: сортировки, деревья, хэш-таблицы. Использование компаратора ни у кого удивления не вызывает.
Алгоритмы, использующие обобщённое сложение никому кроме меня не известны: например, алгоритм Дейкстры на графах. Поэтому использование моноида вызывает бурю эмоций.

Для обобщённого сравнения ты реализуешь IComparer<T> или IEqualityComparer<T>. Аналогично, для обобщённого сложения (обобщённой бинарной операции) ты реализуешь IMonoid<T>. Или, если ты больше не инженер, а уже менеджер, то IGenericAggregationControllerManager<T>, так трудовому народу понятнее.

S>1. Рассказ про то, что у инта сразу два моноида, был убедителен, но непонятно, как именно это можно применить. Ну, кроме вырожденного случая "давайте проагрегируем массив интов с использованием 1 и * в качестве нашего моноида".


Давай не про инты, а про float'ы, ок? Аддитивный моноид понятно, например, складывать веса дуг вдоль пути на графе. Мультипликативный моноид, например, когда у тебя цепочка процентных ставок: начинаем с 1.0, заплатили налог 13% (домножить на 0.87), получили interest 5% (домножить на 1.05) и так далее.

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

Взя затея вокруг шейпов — это добавить чуть синтаксического сахара вокруг всех этих IEqualityComparer<T>'ов и IMonoid<T>'ов, чтоб передавать не инстансы (они ж все одинаковые stateless), а сами типы. Примерно, как в этой старой статье: https://github.com/MattWindsor91/roslyn/blob/master/concepts/docs/csconcepts.md