Dam*_*ell 6 c# linq functional-programming currying
我最近读到.NET 4的System.String类有一个新的Join方法重载.这个新的重载采用了一个分隔符,IEnumerable<T>它允许将任意集合连接成一个字符串,而无需转换为中间字符串数组.
凉!这意味着我现在可以这样做:
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0);
var list = string.Join(",",evenNums);
Run Code Online (Sandbox Code Playgroud)
......而不是这个:
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.Select(i => i.ToString())
.ToArray();
var list = string.Join(",", evenNums);
Run Code Online (Sandbox Code Playgroud)
...因此节省了将每个项目转换为字符串,然后分配数组.
但是,作为一般编程功能样式的粉丝,特别是C#中的方法链接,我宁愿能够写出这样的东西:
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.string.Join(",");
Run Code Online (Sandbox Code Playgroud)
这不是合法的C#.是的,我可以这样做Enumerable.Aggregate,是的,我可以使用我自己的Join扩展方法来实现它,但是这些方法难以阅读/效率低下并感觉像是一个警察(分别),所以我想尝试做它是一种不同的方式.我到目前为止最接近的是这样的:
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.ApplyTo(
Functional.Curry<string, IEnumerable<object>, string>
(string.Join)(",")
);
Run Code Online (Sandbox Code Playgroud)
...使用以下扩展方法:
public static class Functional
{
public static TRslt
ApplyTo<TArg, TRslt>(this TArg arg, Func<TArg, TRslt> func)
{
return func(arg);
}
public static Func<T1, Func<T2, TResult>>
Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
{
Func<Func<T1, T2, TResult>, Func<T1, Func<T2, TResult>>> curried
= f => x => y => f(x, y);
return curried(func);
}
}
Run Code Online (Sandbox Code Playgroud)
这非常冗长,需要显式定义参数和字符串的返回类型.我想要使用的加载过载,并依赖于C#4的方差特性,因为我们将其中一个参数定义为IEnumerable而不是IEnumerable.
你能找到一种更简洁的方法来实现这种方法链式编程吗?
这个挑战是试图在C#中找到一种简洁的方式来解决具有多重载荷的功能 - 这只是为了好玩!
有什么不对:
var list = string.Join(",",Enumerable.Range(1, 100).Where(i => i%2 == 0));
Run Code Online (Sandbox Code Playgroud)
我真的不明白这不是函数式编程.它不那么紧密,真实.但功能程序不是关于链接,而是关于编写更多的声明性语句,这在我的书中正在做.当然,如果你真的希望它被链接,你可以这样做:内部 /加入字符串数组的LINQ方式是什么?