Mulan
Mulan

Reputation: 135416

How to write a curried method in C#?

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

Answers (4)

louthster
louthster

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

Currying source

Partial application source

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

CRice
CRice

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

Stephen Brickner
Stephen Brickner

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

Lee
Lee

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

Related Questions