Reputation: 135416
The following code will run and print 11
using System;
class MainClass {
public static void Main (string[] args) {
Func<int, int, int> _Add = (x,y) => x + y;
var Add = Curry(_Add);
int z = Add (5) (6);
Console.WriteLine(z); // 11
}
public static Func<T1, Func<T2, T3>> Curry<T1, T2, T3>(Func<T1, T2, T3> f) {
return x => y => f(x, y);
}
}
But I was wondering if it's possible to define the curried method on the class rather than locally
public static ... Add(...) { /* define curried form using Curry helper */
return f(x, y);
}
It should be callable like this
public static void Main(string[] args) {
Add (5) (6); // => should return 11
}
If I have a lot of methods that I want curried, it would be nice to use a helper function to define them. Writing each one by hand will be too tiring. Anyway, I can't figure out the proper syntax for this. Please help. I'm a C# noob.
Upvotes: 2
Views: 500
Reputation: 1662
Ideally you want currying and partial-application, currying becomes quite inefficient when you have many parameters. When I did it I implemented a ton of static methods called curry
and par
that can handle up to 10 parameters and partially apply N values.
Here's an example for 4 parameters:
public static Func<T1, Func<T2, Func<T3, Func<T4, R>>>> curry<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> f) =>
(T1 a) => (T2 b) => (T3 c) => (T4 d) => f(a, b, c, d);
It quickly ends up with many nested delegates. And this is where partial application comes in:
public static Func<T4, R> par<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> func, T1 a, T2 b, T3 c) =>
(T4 d) => func(a, b, c, d);
To use the curyring example above you would do:
var f = curry(func);
var r = f(1)(2)(3)(4);
But often partial application is what you want:
var f = par(1,2,3);
var r = f(4);
This is fully implemented in my C# functional library: language-ext
You can take those source files as-is, there's no external dependencies.
In your example you could declare a the Add
method thus:
class Test
{
public static readonly Func<int, Func<int, int>> Add => x => y => x + y;
}
Or the classic way and use the curry
function:
class Test
{
public static readonly int Add(int x, int y) => x + y;
}
var add = curry(Test.Add);
var r = add(1)(2);
Or partially apply:
class Test
{
public static int Add(int x, int y) => x + y;
}
var addOne = par(Test.Add, 1);
var r = addOne(2);
Upvotes: 0
Reputation: 12567
Using your original curry a constructor can initialize the functions. How flexible do you need your types to be?
public static class Test
{
static Test()
{
Add = Curry<int,int,int>((x, y) => x+y);
Multiply = Curry<int,int,int>((x, y) => x*y);
}
public static Func<int, Func<int, int>> Add { get; }
public static Func<int, Func<int, int>> Multiply { get; }
public static Func<T1, Func<T2, T3>> Curry<T1, T2, T3>(Func<T1, T2, T3> f) {
return x => y => f(x, y);
}
}
For just a bunch of method implementations they could be contained like this
public static class Test
{
public static Func<int, Func<int, int>> Add => x => y => x + y;
public static Func<int, Func<int, int>> Multiply => x => y => x * y;
}
Upvotes: 1
Reputation: 2602
To curry the function you first need to pass a function to a function.
void Main()
{
var test = Add(() => 5)(6);
test.Dump();
}
public Func<int, int> Add(Func<int> a)
{
return (x) => x + a();
}
//returns 11
Upvotes: 0
Reputation: 144206
You can just return a Func<int, int>
from Add
:
public static Func<int, int> Add(int x) {
return y => x + y;
}
or declare it as a property:
public static Func<int, Func<int, int>> Add
{
get { return x => y => x + y; }
}
Upvotes: 3