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

Сообщение Re[5]: Монады - пример где бы были полезны... от 29.08.2019 14:06

Изменено 29.08.2019 14:12 Jack128

Re[5]: Монады - пример где бы были полезны...
Здравствуйте, takTak, Вы писали:


T>про монаду Identity я совсем не понял, зачем она вообще?


Ну монада — это что то типа интерфейса c методом bind, а Identity — реализация этого интерфейса. Я там выше написал во что транслируется код a + b. Если a имеет тип int, то такая трансформация невозможно, потому что у типа int нету метода bind. Значит нам нужна обертка с таким методом. Я написал её явно, но потенциально за меня её мог бы сгенерить компилятор.

T>lift'идь — это перевести к монадическому виду?


lift'инг операторов в c# — это возможность использовать операторы с типом Nullable<T>, если эти операторы определены для типа Т.
То есть так как для типа int определён оператор + , то я могу написать Nullable<int> x, y; x + y.
А у типа struct A {} оператора + нету, поэтому Nullable<A> x, y; x + y — не скомпилируется. Выше я пожелал чтоб операторы лифтились не только для NUllable, а для любого монадического типа

T>т.е. польза от "хай кайндед полимофизм" в том, что нужно меньше проверки типов или что-то другое?


Польза в том же, что и польза от обычных дженериков, но немного на другом уровне. Эта концепция вообще говоря к монадам отнашения не имеет. ТО есть может существовать и приносить пользу без них, а вот монадам без HKP(high kinded polimorphism) — туго.

Вернемся к примеру со средним. Немного изменю его
M<double> Average<M<_>>(IEnumerable<M<int>> ints) {
   var sum = new M<double>(0.0);
   var count = 0;
   foreach(var v in ints) {
      sum = sum + v;
      count++;
   }
   return count > ? (sum / count) : new M<double>(0);
}

то есть если я передал список Nullable<int> то на выходе должен получить Nullable<double> . Если на входе список из Task<int> то на выходе Task<double> должен быть. Обычными дженериками такого не добьёшься. А вот шаблонами из С++ наcколько я понимаю можно.
Re[5]: Монады - пример где бы были полезны...
Здравствуйте, takTak, Вы писали:


T>про монаду Identity я совсем не понял, зачем она вообще?


Ну монада — это что то типа интерфейса c методом bind, а Identity — реализация этого интерфейса. Я там выше написал во что транслируется код a + b. Если a имеет тип int, то такая трансформация невозможно, потому что у типа int нету метода bind. Значит нам нужна обертка с таким методом. Я написал её явно, но потенциально за меня её мог бы сгенерить компилятор.

T>lift'идь — это перевести к монадическому виду?


lift'инг операторов в c# — это возможность использовать операторы с типом Nullable<T>, если эти операторы определены для типа Т.
То есть так как для типа int определён оператор + , то я могу написать Nullable<int> x, y; x + y.
А у типа struct A {} оператора + нету, поэтому Nullable<A> x, y; x + y — не скомпилируется. Выше я пожелал чтоб операторы лифтились не только для NUllable, а для любого монадического типа

T>т.е. польза от "хай кайндед полимофизм" в том, что нужно меньше проверки типов или что-то другое?


Польза в том же, что и польза от обычных дженериков, но немного на другом уровне. Эта концепция вообще говоря к монадам отнашения не имеет. ТО есть может существовать и приносить пользу без них, а вот монадам без HKP(high kinded polimorphism) — туго.

Вернемся к примеру со средним. Немного изменю его
M<double> Average<M<_>>(IEnumerable<M<int>> ints) {
   var sum = new M<double>(0.0);
   var count = 0;
   foreach(var v in ints) {
      sum = sum + v;
      count++;
   }
   return count > ? (sum / count) : new M<double>(0);
}

то есть если я передал список Nullable<int> то на выходе должен получить Nullable<double> . Если на входе список из Task<int> то на выходе Task<double> должен быть. Обычными дженериками такого не добьёшься. А вот шаблонами из С++ наcколько я понимаю можно.

Вот этот момент, то что я дженериком аргументом передаю не конкретный тип (ну например Nullable<int>), а open generic type — вот это и есть полимофизм высшего порядка