Сообщение 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) — туго.
Вернемся к примеру со средним. Немного изменю его
то есть если я передал список Nullable<int> то на выходе должен получить Nullable<double> . Если на входе список из Task<int> то на выходе Task<double> должен быть. Обычными дженериками такого не добьёшься. А вот шаблонами из С++ наcколько я понимаю можно.
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) — туго.
Вернемся к примеру со средним. Немного изменю его
то есть если я передал список Nullable<int> то на выходе должен получить Nullable<double> . Если на входе список из Task<int> то на выходе Task<double> должен быть. Обычными дженериками такого не добьёшься. А вот шаблонами из С++ наcколько я понимаю можно.
Вот этот момент, то что я дженериком аргументом передаю не конкретный тип (ну например Nullable<int>), а open generic type — вот это и есть полимофизм высшего порядка
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 — вот это и есть полимофизм высшего порядка