【发布时间】:2011-05-22 19:17:28
【问题描述】:
假设我想实现一个函数式组合,像这样:
public Func<T,T> Compose<T>(Func<T,T> f, Func<T,T> g)
{
return new Func<T,T>( x => f(g(x)));
}
现在在实践中,我可以像这样使用 Compose() fn:
public String ToUpper(String s) { return s.ToUpper(); }
public String Replicate(String s) { return s+s; }
public void Run()
{
var h = Compose<String>(ToUpper, Replicate);
System.Console.WriteLine("{0}", h("fred"));
}
结果是FREDFRED
。
有没有办法使用更简单的语法来调用 Compose?我试过这样:
var h = Compose(ToUpper, Replicate);
...但我得到一个编译错误:
错误 CS0411:无法从用法中推断方法“FunctionalTest.Compose(System.Func, System.Func)”的类型参数。尝试明确指定类型参数。
很好理解。我想知道是否有可能以不同的方式声明它并让推论真正起作用。
编辑
问题的根源:我正在观看本科生函数式编程课程的在线讲座,加州大学伯克利分校的 CS61A。 (在 youtube 上找到)。我没有接受过任何正式的 FP 培训,我想我可能会学到一些东西。教授使用scheme,他谈到scheme + lisp是纯粹的函数式语言,而其他语言则不然。他特别指出 Pascal、C、C++ 和 Java(但不是 C#)缺乏函数式能力,并表示很难用这些语言进行函数式组合(“没有站在你的头上”)。他断言指向函数的指针(在 C、C++ 中可用)与函数“实体”不同,即 lambda。我明白了。
有趣 - 他没有提到 Javascript 或 C#,我认为它们都是主流语言,它们都具有很好的功能。 (我不知道 F#。)
我觉得奇怪的是,这是去年(14 个月前)的演讲,但他似乎不了解主流现代语言的功能方面。
所以我一直在做练习,但我没有使用 scheme 或 lisp,而是使用 C#。并且还用 Javascript 做其中的一些。
感谢大家的高质量回复。
【问题讨论】:
-
切向提示:您可以像这样进一步概括您的
Compose
方法:paste.pocoo.org/show/393393 -
函数组合没有更通用的类型吗?
Func<A,C> Compose<A,B,C>(Func<B,C> f, Func<A,B> g)
(翻译自 Haskell(.) :: (b -> c) -> (a -> b) -> a -> c
)。