amb-operator的非确定性选择

Dar*_*rio 5 .net c# continuations functional-programming non-deterministic

是否可以在C#中实施McCarthy的amb-operator用于非确定性选择?

显然.NET缺乏持续支持但yield return可能有用.这可能在其他静态.NET语言中如F#吗?

Dan*_*ker 5

是的,yield return是一种延续形式.虽然许多有用的情况下,LINQ的提供的函数运算符,让你插在一起慵懒的序列发生器,所以其实在C#3,没有必要用yield return这么多(添加自己的更多的LINQ风格的扩展插件时除外库中的空白,例如Zip,Unfold).

在该示例中,我们通过强力分解整数.基本上C#中的相同示例可以使用内置的Linq运算符完成:

var factors = Enumerable.Range(2, 100)
        .Join(Enumerable.Range(2, 100), 
              n => 1, n => 1, (i, j) => new { i, j })
        .First(v => v.i*v.j == 481);

Console.WriteLine("Factors are " + factors.i + ", " + factors.j);
Run Code Online (Sandbox Code Playgroud)

这里的起点是我的两次调用Enumerable.Range,内置于Linq,但您可以将自己实现为:

IEnumerable<int> Range(int start, int stop)
{
    for (int n = start; n < stop; n++)
        yield return n;
}
Run Code Online (Sandbox Code Playgroud)

有两个奇数参数n => 1,n => 1参数为Join.我选择1作为Join匹配项目时使用的关键值,因此所有组合都匹配,因此我可以测试范围中的每个数字组合.

然后我将这对值转换为一种元组(匿名类型):

(i, j) => new { i, j })
Run Code Online (Sandbox Code Playgroud)

最后,我选择了第一个满足测试要求的元组:

.First(v => v.i*v.j == 481);
Run Code Online (Sandbox Code Playgroud)

更新

调用中的代码First不一定只是一个简短的测试表达式.如果测试失败,它可能是需要"重启"的大量命令性代码:

.First(v => 
       {
           Console.WriteLine("Aren't lambdas powerful things?");

           return v.i*v.j == 481;
       );
Run Code Online (Sandbox Code Playgroud)

因此,可能需要使用不同值重新启动的程序部分就在lambda中.每当lambda想要用不同的值重新启动它时,它只返回false - 相当于amb不带参数调用.

  • 不错的代码 - 但它的效果与 amb 完全不同。Amb 选择其值以使整个代码不会失败,而不仅仅是以下计算。 (2认同)

z5h*_*z5h 5

这不是你的问题的答案,但它可能会得到你想要的.

amb用于非确定性计算.您可能知道,Prolog是一种非确定性语言,它使用统一概念将值绑定到变量(基本上是amb最终要做的事情).

C#中有一个名为YieldProlog的功能实现.正如您所猜测的那样,收益率算子是这一点的重要必要条件.

http://yieldprolog.sourceforge.net/