This post is dedicated to extend a functionality coded in this previous post:
FSharp InvokeFast
Curry is a basic concept on functional programming, let's extend the defintion wth this post
Curry: Wikipedia, the free encyclopedia
In this post we code with C# Real Curry with the implementation of F#
We begin with the definition of a Curry Interface
With this implementation
The usability is via lambda Expressions
METHOD SOFTWARE ® 2022
FSharp InvokeFast
Curry is a basic concept on functional programming, let's extend the defintion wth this post
Curry: Wikipedia, the free encyclopedia
In this post we code with C# Real Curry with the implementation of F#
We begin with the definition of a Curry Interface
public interface ICurriedFunction<T, S, M, R>
{
/// <summary> Invokes the value Result
R InvokeResult();
/// <summary> Sets Arg1, Arg2, Arg3
ICurriedFunction<T, S, M, R> SetArgs(Expression<Func<T>> funcArg1, Expression<Func<T, S>> funcArg2, Expression<Func<S, M>> funcArg3);
/// <summary> Sets the Result and Curried functions
ICurriedFunction<T, S, M, R> SetResultFunction(Converter<M, R> converter);
}
With this implementation
public abstract class SpeciedFunction<R>
{
public abstract R InvokeResult();
}
public class CurriedFunction<T, S, M, R> : SpeciedFunction<R>, ICurriedFunction<T, S, M, R>
{
private FSharpFunc<T, FSharpFunc<S, FSharpFunc<M, R>>> Func { get; set; }
private FSharpFunc<M, R> ResultFunc { get; set; }
private FSharpFunc<S, FSharpFunc<M, R>> CurriedFunc { get; set; }
private Expression<Func<T>> Arg1 { get; set; }
private Expression<Func<T, S>> Arg2 { get; set; }
private Expression<Func<S, M>> Arg3 { get; set; }
public override R InvokeResult()
{
T argValue1 = this.Arg1.Compile()();
S argValue2 = this.Arg2.Compile()(argValue1);
M argValue3 = this.Arg3.Compile()(argValue2);
R result = FSharpFunc<T, S>.InvokeFast<M, R>(this.Func, argValue1, argValue2, argValue3);
return result;
}
public ICurriedFunction<T, S, M, R> SetResultFunction(Converter<M, R> converter)
{
this.ResultFunc = converter;
this.CurriedFunc = FuncConvert.ToFSharpFunc<S, FSharpFunc<M, R>>(s => this.ResultFunc);
this.Func = FuncConvert.ToFSharpFunc<T, FSharpFunc<S, FSharpFunc<M, R>>>(t => this.CurriedFunc);
return this;
}
public ICurriedFunction<T, S, M, R> SetArgs(Expression<Func<T>> funcArg1, Expression<Func<T, S>> funcArg2, Expression<Func<S, M>> funcArg3)
{
this.Arg1 = funcArg1;
this.Arg2 = funcArg2;
this.Arg3 = funcArg3;
return this;
}
}
The usability is via lambda Expressions
void testCurried()
{
ICurriedFunction<Test, string, double, bool> curry = new CurriedFunction<Test, string, double, bool>();
curry.SetResultFunction(getBool)
.SetArgs(() => getTest(),
(s) => getTestString(s),
(d) => getDouble(d));
bool result = curry.InvokeResult();
}
Test getTest() => new()
{
Id = 1024,
Text = "Test Real Curry"
};
string getTestString(Test test) => (test.Id * 4000).ToString();
double getDouble(string value) => Convert.ToDouble(value);
bool getBool(double i) => i > 50;
METHOD SOFTWARE ® 2022