【问题标题】:How to use "struct" with currying "Func"?如何使用“struct”和currying“Func”?
【发布时间】:2018-12-28 09:20:53
【问题描述】:

“Curry”让我很感兴趣,所以我尝试将它整合到 C#“Func”中。 有一个简单的练习来读取一些正值,然后对这个系列进行求和、计数和平均。以下列表是第一次试用:

Func<int, Func<int, int>> CurriedSum = x => y => x + y;//Declare curryied sum
Func<int, int> CurriedCount = x => x + 1;//Declare counting
Console.Write("Please input the first number in a series: ");//Prompt
int inputValue = int.Parse(Console.ReadLine());//User's input
int sum = inputValue;//original sum = 1st value
int count = CurriedCount(0);//count from 0
do
{
    Console.Write("Please input the next number in a series (0 will exit):");//Prompt
    inputValue = int.Parse(Console.ReadLine());//User's input
    if (inputValue > 0)//Accept positive number only
    {
        sum = CurriedSum(inputValue)(sum);//Call curried function to sum
        count = CurriedCount(count);//Call function to count
        Console.Write($"=> Sum of {count} numbers is {sum}.");//Output
        Console.WriteLine($" Mean is {(float)resultInt/count}.");//Output
    }
} while (inputValue > 0);//loop until 0 or any negative number

此试验有效。但是,以下第二次尝试失败:

internal struct MyStruct
{
    public int Sum;
    public int Count;
    public float Mean;
}//located above static void Main(string[] args)

//Func<int, Func<int, MyStruct>> CurriedSumMean = x => y =>//wrong
Func<int, Func<MyStruct, MyStruct>> CurriedSumMean = x => y =>//*correct*
{
    MyStruct result;//no need to initialize
    //result.Sum = x + y;//wrong
    //result.Count++;//Error here!
    result.Sum = x + y.Sum;//*correct*
    result.Count = y.Count + 1;//*correct*
    result.Mean = result.Sum / result.Count;
    return result;
};//Calculate and return curried sum, counting and average
MyStruct series;//Declare a series
Console.Write("Please input the first number in a series: ");//Prompt
inputValue = int.Parse(Console.ReadLine());//User's input
series.Sum = inputValue;//original sum = 1st value
series.Count = 1;//count from 1
series.Mean = inputValue;//original average = 1st value
do
{
    Console.Write("Please input the next number in a series (0 will exit):");//Prompt
    inputValue = int.Parse(Console.ReadLine());//User's input
    if (inputValue > 0)//Accept positive number only
    {
        series = CurriedSumMean(inputValue)(series);//*it works!*
        Console.Write($"=> Sum of {series.Count} numbers is {series.Sum}.");//Output
        Console.WriteLine($" Mean is {series.Mean}.");//Output
    }
} while (inputValue > 0);//loop until 0 or any negative number

Visual Studio 2017发现两个错误。一个是result.Count++;在柯里化函数函数 CurriedSumMean 中定义。另一个错误是 series = CurriedSumMean(inputValue)(series)。

如何正确使用“struct”和“Func”,尤其是柯里化? 非常感谢您的帮助。

【问题讨论】:

  • @ojlovecd 和 l33t,你们都是对的!我尝试初始化对象“结果”并且它有效。但是,我将 curried 函数更改为 "Func> CurriedSumMean = x => y =>" 以接受 MyStruct 的系列。因此,“系列 = CurriedSumMean(inputValue)(series);”没有错误。还有“result.Count++;”必须改为“result.Count = y.Count + 1;”
  • @vasily.sib,你是对的!我尽量保留原始声明“MyStruct 结果;”它有效。无需初始化结构。但是Func必须修改为“Func>”,即第一个MyStruct是上次调用的输出类型,第二个MyStruct是本次调用的输出类型。谢谢大家。

标签: c# currying


【解决方案1】:

你必须在使用之前初始化对象

MyStruct result = new MyStruct();

您不能将结构对象转换为整数。我想你应该在这里使用 series.Sum

series = CurriedSumMean(inputValue)(series.Sum);

【讨论】:

  • MyStructstruct - 无需初始化
  • MyStructstruct - 需要初始化。这是正确的答案。
  • @l33t,为什么需要初始化?对于MyStruct result1;MyStruct result2 = new MyStruct();,此结构将完全相同(我的意思是result1.Sum == result2.Sum &amp;&amp; result1.Count == result2.Count &amp;&amp; result1.Mean == result2.Mean)。
  • @vasily.sib:你们都被结构性所吸引,但这无关紧要。 所有的局部变量在被读取之前必须被赋值。所有字段和数组元素都分配了默认值;它们不需要明确分配。无论类型是值类型还是引用类型都是如此
  • 也就是说,在 C# 语义分析器中曾经存在一个错误,其中作为只有私有成员的结构的局部变量被自动标记为已初始化,因为语义分析器实际上检查“都是这个结构成员在使用之前初始化了吗?”它跳过了无法访问的成员。我不知道该错误是否已在最近的 C# 版本中得到修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-20
相关资源
最近更新 更多