LINQ相当于f#的builder.Zero()?

Jon*_*son 4 c# f# monoids

所以,我已经沉迷于f#的计算表达式和自定义构建器.我必须在日常工作的大部分时间里使用c#,但仍然希望将LINQ表达式与我自己的monads/monoids一起使用.有没有人知道是否有ac#analog to f#Zero方法?

相关的f#docs

这是我在f#中所做的:

type OptionBuilder() =
    member x.Bind(v,f) = Option.bind f v
    member x.Return v = Some v
    member x.ReturnFrom o = o
    member x.Zero() = Option.None

let option = OptionBuilder()

// Example usage (I want something similar from c#)

let t : Option<int> =
    option { if false then return 5 }
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 10

我不确定你在这里问什么,但我会试一试.考虑澄清问题.

C#中的等价物ifelsemonadic工作流中的no相同:

from a in b
where c(a)
select a
Run Code Online (Sandbox Code Playgroud)

逻辑上这相当于(使用你的Bind,Return和Zero)

Bind(b, a => c(a) ? Return(a) : Zero)
Run Code Online (Sandbox Code Playgroud)

但是C#不会将where子句降低为SelectMany(这就是C#所谓的Bind).C#将查询理解中的Where子句降低到调用

Where(M<T>, Func<T, bool>)
Run Code Online (Sandbox Code Playgroud)

简而言之:C#以查询理解的形式具有任意的monadic工作流程; 具有Select,SelectMany,Where等的任何monadic类型都可以用于理解.但它并没有真正推广到具有明确零的加性monad.相反,"Where"应该具有我在上面提到的绑定操作的语义:如果项与谓词匹配,它应该具有与将单个值绑定到末尾相同的效果,如果不匹配则应该具有零值.

显然,序列的"Where"就是这样.如果你有[a,b,c]并希望过滤掉b,那就像连在一起[[a],[],[c]]一样.但是当然,实际构建和连接所有这些小序列会非常低效.该效果必须是一样的,但实际操作可能更为有效.

C#真的被设计为支持非常特定的monad:序列monad via yield和query comprehensions,continuation comonad via await等等.我们没有将其设计为启用任意monadic工作流,如您在Haskell中看到的那样.

这是否回答你的问题?