我一直在努力完成这篇文章:
http://blogs.msdn.com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx
...第 1 页上的某些内容让我感到不舒服。特别是,我试图围绕 Compose<>() 函数进行思考,并为自己编写了一个示例。考虑以下两个 Func:
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));
}
}
美好的。所以现在你可以说:
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));
}
}
这里是歧义。这两个函数没有重叠签名吗?是的。这甚至可以编译吗?是的。哪一个被调用?第二个(显然给你“错误”的结果)被调用。如果您注释掉任何一个函数,它仍然可以编译,但您会得到不同的结果。
这似乎是在吹毛求疵,但这里有一些东西深深地冒犯了我的感情,我不能指望它。它与扩展方法有关吗?它与lambda有关吗?或者它是否与 Func<> 允许您参数化返回类型有关?我不确定。
我猜这一切都在规范中的某个地方得到解决,但我什至不知道谷歌要找到什么。
帮助!