4 c# lisp functional-programming
我正在用C#编写一个小的Lisp解释器,它基本上已经工作了.目前我正在使用一个界面来表示功能:
public interface LispFunction
{
object Apply(ArrayList parameters);
}
Run Code Online (Sandbox Code Playgroud)
接口由多个类实现,用于内部(标准)函数,lambdas,宏扩展,通过反射调用.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
Run Code Online (Sandbox Code Playgroud)
即来到我的脑海里的第一件事是用Func<...>
,但我不得不使用大量重载方法Func<a>
,Func<a, b>
,Func<a, b, c>
等等.
C#中是否有可能接受随后通过反射调用的任意lambdas?
C#中是否有可能接受随后通过反射调用的任意lambdas?
那么你可以编写一个方法来获取一个任意的委托:
public void AddFunction(string name, Delegate function)
Run Code Online (Sandbox Code Playgroud)
但是,从lambda表达式转换必须作为特定委托,因此您需要:
Func<bool, string, string> function = (a, b) => a ? b : "whoops"
foo.GlobalEnvironment.AddFunction("test", function);
Run Code Online (Sandbox Code Playgroud)
或者在通话中投下:
foo.GlobalEnvironment.AddFunction("test",
(Func<bool, string, string>)((a, b) => a ? b : "whoops"));
Run Code Online (Sandbox Code Playgroud)
你可以将所有重载放在一个地方,保持AddFunction
完全一般,但有一个像这样的静态类(有点像Tuple
):
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
}
Run Code Online (Sandbox Code Playgroud)
这个类基本上只是为了方便而存在.然后你打电话:
foo.GlobalEnvironment.AddFunction("test",
Func.Create((bool a, string b) => a ? b : "whoops"));
Run Code Online (Sandbox Code Playgroud)