通用函数<&燃气轮机;输入c#

通用函数<&燃气轮机;输入c#,c#,functional-programming,lisp,C#,Functional Programming,Lisp,我正在用C#编写一个小的Lisp解释器,它基本上已经可以工作了。目前,我正在使用一个接口来表示函数: public interface LispFunction { object Apply(ArrayList parameters); } 接口由内部(标准)函数、lambda、宏扩展、通过反射调用.net对象中的方法等的多个类实现。请注意,速度在这里不是一个问题,只是让口译员工作并在工作中使用它的乐趣 现在我想让我的小Lisp接受在解释器中使用的任意C#lambdas,如下所示: L

我正在用C#编写一个小的Lisp解释器,它基本上已经可以工作了。目前,我正在使用一个接口来表示函数:

public interface LispFunction
{
    object Apply(ArrayList parameters);
}
接口由内部(标准)函数、lambda、宏扩展、通过反射调用.net对象中的方法等的多个类实现。请注意,速度在这里不是一个问题,只是让口译员工作并在工作中使用它的乐趣

现在我想让我的小Lisp接受在解释器中使用的任意C#lambdas,如下所示:

Lisp foo = new Lisp();
foo.GlobalEnvironment.AddFunction("test", (bool a, int b) => a ? b : "whoops");
foo.Eval(foo.Read("(test #t 5)")); // Should evaluate to (object) 5
我想到的第一件事是使用
Func
,但我必须为
Func
Func
Func
等使用许多重载方法

在C#中是否有可能接受稍后通过反射调用的任意lambda

在C#中是否有可能接受稍后通过反射调用的任意lambda

您可以编写一个方法来接受任意委托:

但是,lambda表达式的转换必须作为特定委托,因此您需要:

Func<bool, string, string> function = (a, b) => a ? b : "whoops"
foo.GlobalEnvironment.AddFunction("test", function);
这个类基本上只是为了方便而存在。然后你会打电话:

foo.GlobalEnvironment.AddFunction("test",
    Func.Create((bool a, string b) => a ? b : "whoops"));

…就这样,谢谢!现在我将使用cast-within-call变量,稍后当涉及到抛光时,我将切换到便利方法。完整调用看起来像这样的ATM:
lisp.GlobalEnvironment.Define(Symbol.GetSymbol(“test”),(Func)((a,b)=>b?(object)a:(object)“哇”)…刚注意到你的回答是在我的问题四分钟后。会问“你是Jon Skeet吗?!”。然后我注意到了。Mind==blow.OK,现在看起来像是我想要的:)
lisp.GlobalEnvironment.AddFunction(“test”,(int a,bool b)=>b?a:(object)“哎哟”)
foo.GlobalEnvironment.AddFunction("test",
    (Func<bool, string, string>)((a, b) => a ? b : "whoops"));
public static class Func
{
    public Func<TResult> Create(Func<TResult> function) { return function; }

    public Func<T1, TResult> Create(Func<T1, TResult> function)
    {
        return function;
    }

    public Func<T1, T2, TResult> Create(Func<T1, T2, TResult> function)
    {
        return function;
    }

    // etc
}
foo.GlobalEnvironment.AddFunction("test",
    Func.Create((bool a, string b) => a ? b : "whoops"));