以下代码将运行并打印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);
}
}
但我想知道是否可以在课堂上定义咖喱方法而不是在本地
public static ... Add(...) { /* define curried form using Curry helper */
return f(x, y);
}
它应该像这样可以调用
public static void Main(string[] args) {
Add (5) (6); // => should return 11
}
如果我有很多方法需要咖喱,那么使用辅助函数来定义它们会很不错。手工编写每一个都太累人了。无论如何,我无法弄清楚这个的正确语法。请帮忙。我是C#noob。
答案 0 :(得分:3)
您只需从Func<int, int>
Add
即可
public static Func<int, int> Add(int x) {
return y => x + y;
}
或将其声明为财产:
public static Func<int, Func<int, int>> Add
{
get { return x => y => x + y; }
}
答案 1 :(得分:1)
使用原始咖喱构造函数可以初始化函数。您需要多大的灵活性?
CASE
对于一堆方法实现,它们可以像这样包含
update Employee
set Gender = (
case Gender when 'M' then 'F'
when 'F' then 'M'
else Gender end
);
答案 2 :(得分:0)
要首先解决函数,首先需要将函数传递给函数。
//Example of what I have to to right now.
public class Weapon
{
public string m_name;
public int m_attack_damage;
// ETC...
}
//This is an example class that will contain game logic handling Actor
//currently.. Because I have a type that is not regonized by the Sqlite Database
//it will not create a table/field for this class as a type due to this without a ModelClass wrapper to convert those values.
public class Actor
{
public string m_Name { get; set; } //This translates perfectly to the SQLite database.
public int m_Age { get; set; } //This translates perfectly to the SQLite database.
//THIS WILL NOT TRANSLATE TO THE SQLite DB without a Model Wrapper.
public Weapon m_Weapon { get; set; } //This is a type of a custom class called Weapon.
//This is the model class I need to pass to the Table/Field to be translated correctly.
public ActorDBModel ToDBModel()
{
var model = new ActorDBModel();
model.Name = m_Name;
model.Age = m_Age;
model.Weapon_Name = m_Weapon.m_Name;
model.Weapon_Attack_Damage = m_Weapon.m_attack_damage;
return model
}
//ETC...
}
//THIS IS WHAT I HAVE TO CREATE IN ORDER TO HANDLE THE ABOVE CLASS
public class ActorDBModel
{
public string Name {get; set;}
public string Age {get; set;}
public string Weapon_Name {get; set;} //These are set from the Actor
public int Weapon_Attack_Damage {get; set;} // These are set from the ActorDBModel
//ETC...
}
答案 3 :(得分:0)
理想情况下,您需要进行currying和部分应用,当您有许多参数时,currying变得非常低效。当我这样做时,我实现了大量名为curry
和par
的静态方法,它们最多可以处理10个参数并部分应用N个值。
以下是4个参数的示例:
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);
很快就会有很多嵌套的委托。这就是部分应用程序的用武之地:
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);
要使用上面的curyring示例,您可以这样做:
var f = curry(func);
var r = f(1)(2)(3)(4);
但通常部分应用是你想要的:
var f = par(1,2,3);
var r = f(4);
您可以按原样获取这些源文件,没有外部依赖项。
在您的示例中,您可以声明Add
方法:
class Test
{
public static readonly Func<int, Func<int, int>> Add => x => y => x + y;
}
或者经典方式并使用curry
函数:
class Test
{
public static readonly int Add(int x, int y) => x + y;
}
var add = curry(Test.Add);
var r = add(1)(2);
或部分适用:
class Test
{
public static int Add(int x, int y) => x + y;
}
var addOne = par(Test.Add, 1);
var r = addOne(2);