Я пытался пробиться сквозь эту статью:
http://blogs.msdn.com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx
... И что-то на странице 1 заставило меня чувствовать себя неловко. В частности, я пытался обернуть голову вокруг функции Compose <> (), и я написал пример для себя. Рассмотрим следующие две функции:
Func<double, double> addTenth = x => x + 0.10;
Func<double, string> toPercentString = x => (x * 100.0).ToString() + "%";
Нет проблем! Легко понять, что делают эти двое.
Теперь, следуя примеру из статьи, вы можете написать универсальный метод расширения для составления этих функций, например так:
public static class ExtensionMethods
{
public static Func<TInput, TLastOutput> Compose<TInput, TFirstOutput, TLastOutput>(
this Func<TFirstOutput, TLastOutput> toPercentString,
Func<TInput, TFirstOutput> addTenth)
{
return input => toPercentString(addTenth(input));
}
}
Fine. Так что теперь вы можете сказать:
string x = toPercentString.Compose<double, double, string>(addTenth)(0.4);
И вы получите строку "50%"
Пока все хорошо.
Но здесь есть что-то неоднозначное. Допустим, вы пишете другой метод расширения, так что теперь у вас есть две функции:
public static class ExtensionMethods
{
public static Func<TInput, TLastOutput> Compose<TInput, TFirstOutput, TLastOutput>(
this Func<TFirstOutput, TLastOutput> toPercentString,
Func<TInput, TFirstOutput> addTenth)
{
return input => toPercentString(addTenth(input));
}
public static Func<double, string> Compose<TInput, TFirstOutput, TLastOutput>(this
Func<double, string> toPercentString,
Func<double, double> addTenth)
{
return input => toPercentString(addTenth(input + 99999));
}
}
В этом двусмысленность. Разве эти две функции не имеют перекрывающихся подписей? Да. Это даже компилируется? Да. Какой из них называется? Второй (который явно дает вам «неправильный» результат) вызывается. Если вы закомментируете какую-либо функцию, она все еще компилируется, но вы получите другие результаты.
Это похоже на придирку, но есть кое-что, что глубоко оскорбляет мою чувствительность, и я не могу это понять. Это имеет отношение к методам расширения? Связано ли это с лямбдами? Или это связано с тем, как Func <> позволяет параметризовать тип возвращаемого значения? Я не уверен.
Я предполагаю, что все это указано где-то в спецификации, но я даже не знаю, что Google может найти это.
Помощь!