Joa*_*nge 29 .net c# haskell composition
在C#的最新版本,我可以这样做这个?
我觉得linq是最接近的,但那是链接,而不是功能组合,对吧?
Dav*_*vy8 17
public static class Extensions
{
public static Func<T, TReturn2> Compose<T, TReturn1, TReturn2>(this Func<TReturn1, TReturn2> func1, Func<T, TReturn1> func2)
{
return x => func1(func2(x));
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Func<int, int> makeDouble = x => x * 2;
Func<int, int> makeTriple = x => x * 3;
Func<int, string> toString = x => x.ToString();
Func<int, string> makeTimesSixString = toString.Compose(makeDouble).Compose(makeTriple);
//Prints "true"
Console.WriteLine(makeTimesSixString (3) == toString(makeDouble(makeTriple(3))));
Run Code Online (Sandbox Code Playgroud)
Doc*_*own 14
我没有让编译器检查这个,但这应该是可能的:
public static Func<T3,T1> my_chain<T1, T2, T3>(Func<T2,T1> f1, Func<T3,T2> f2)
{
return x => f2(f1(x));
}
Run Code Online (Sandbox Code Playgroud)
Max*_*dov 12
在C#中没有特定的操作符/"语法糖"(但是,在F#中,您将使用>>
运算符).
Matthew Podwysocki 有一篇关于这个主题的博文.他在C#中建议这种结构:
public static class FuncExtensions
{
public static Func<TSource, TResult> ForwardCompose<TSource, TIntermediate, TResult>(
this Func<TSource, TIntermediate> func1, Func<TIntermediate, TResult> func2)
{
return source => func2(func1(source));
}
}
Func<Func<int, int>, IEnumerable<int>, IEnumerable<int>> map = (f, i) => i.Select(f);
Func<Func<int, bool>, IEnumerable<int>, IEnumerable<int>> filter = (f, i) => i.Where(f);
Func<int, Func<int, int, int>, IEnumerable<int>, int> fold = (s, f, i) => i.Aggregate(s, f);
// Compose together
var mapFilterFold = map.Apply(x => x * x * x)
.ForwardCompose(filter.Apply(x => x % 3 == 0))
.ForwardCompose(fold.Apply(1, (acc, x) => acc * x));
Console.WriteLine(mapFilterFold(Enumerable.Range(1, 10)));
Run Code Online (Sandbox Code Playgroud)
C#没有一流的支持,但实施起来并不是特别困难.你只需要编写很多重载.
public static class Composition
{
public static Func<T2> Compose<T1, T2>(Func<T1> f1, Func<T1, T2> f2)
{
return () => f2(f1());
}
public static Func<T1, T3> Compose<T1, T2, T3>(Func<T1, T2> f1, Func<T2, T3> f2)
{
return v => f2(f1(v));
}
}
Run Code Online (Sandbox Code Playgroud)