Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ等价于f的builder.Zero()?_C#_F#_Monoids - Fatal编程技术网

C# LINQ等价于f的builder.Zero()?

C# LINQ等价于f的builder.Zero()?,c#,f#,monoids,C#,F#,Monoids,所以,我对f的计算表达式和自定义生成器非常上瘾。我不得不在日常工作中使用c语言,但仍然希望在我自己的monad/monoids中使用LINQ表达式。有人知道是否有一个c模拟f的零点法吗 以下是我在f中所做的: 类型选项生成器= 成员x.Bindv,f=Option.bind f v 成员x.返回v=一些v 成员x.ReturnFrom o=o 成员x.Zero=选项。无 let option=OptionBuilder //示例用法我想从c中得到类似的东西 让t:选项= 选项{如果为false,

所以,我对f的计算表达式和自定义生成器非常上瘾。我不得不在日常工作中使用c语言,但仍然希望在我自己的monad/monoids中使用LINQ表达式。有人知道是否有一个c模拟f的零点法吗

以下是我在f中所做的:

类型选项生成器= 成员x.Bindv,f=Option.bind f v 成员x.返回v=一些v 成员x.ReturnFrom o=o 成员x.Zero=选项。无 let option=OptionBuilder //示例用法我想从c中得到类似的东西 让t:选项= 选项{如果为false,则返回5}
我不确定你到底在问什么,但我会试一试。考虑澄清这个问题。

在C语言中,等同于在一元工作流中没有其他内容的if:

from a in b
where c(a)
select a
从逻辑上讲,这相当于使用Bind、Return和Zero

Bind(b, a => c(a) ? Return(a) : Zero)
但是C并没有将where子句降低到SelectMany中,这就是C所称的Bind。C将查询理解中的Where子句降低为调用

Where(M<T>, Func<T, bool>)
简而言之:C以查询理解的形式具有任意的一元工作流;任何带有Select、SelectMany、Where等方法的一元类型都可以用于理解。但它并没有真正推广到显式为零的加法单子。相反,Where应该具有我上面提到的绑定操作的语义:如果项与谓词匹配,它应该具有与将单个值绑定到end相同的效果,如果不匹配,它应该具有零值

很明显,序列在哪里做到了这一点。如果你有[a,b,c]并且想要过滤掉b,这与将[a],[c]]连接在一起是一样的。但当然,实际构建和连接所有这些小序列的效率会非常低。效果必须是相同的,但实际操作可以更加高效

C实际上被设计为支持非常特定的单子:通过产量和查询理解的序列单子,通过等待的延续单子,等等。我们设计它不是为了启用任意一元工作流,正如您在Haskell中看到的那样


这回答了你的问题吗?

除了Eric的精彩回答之外,还有一些代码:

        var result =
        from value in Option.Some(5)
        where false
        select value;
C的LINQ理解寻找相应的扩展方法,其中。下面是一个示例实现:

   public static Option<T> Where<T>(this Option<T> option, Func<T, bool> condition)
        {
            if(option is None || !condition(option.Value))
                return None;

            return option;
        }

Where本身必须定义零大小写。

事实上,Where false必须具有结果为零单子的语义。这是一个很好的见解。由此我们可以看到这样的情况:IObservable monad的零必须是从不调用OnNext的可观察序列。因此,一个小谜题是:任务的零是什么?因为不能允许它逻辑返回结果,所以只有一个选择:Task.FromCancelednew CancellationTokenTrue这是一个合理的选择,但不是唯一的选择;其他的可能是另一个任务有一个异常完成,或者一个永远运行但永远不会完成的任务。这很有趣。在理论意义上,一个比另一个更有说服力,还是仅仅是实现中需要什么行为?永远运行或产生异常在某种意义上都是一种副作用。换句话说:永远运行是无用的/粗鲁的,并且不是每种语言都支持异常作为控制流。在纯函数式编程的世界中,我们可以简单地说Task一开始不是一个加法单子,所以它不需要零。事实上,这个任务也许更适合描述为一个comonad。