yield!
支持在查詢中一定程度上,可以用在select
通常是:
query {
for x in [5;2;0].AsQueryable() do
where (x > 1)
sortBy x
yield! [x; x-1]
} |> Seq.toList // [2;1;5;4]
然而,一般來說,你不能任意散佈查詢和序列操作,因爲它很難定義它們應該如何組成:
query {
for x in [1;2;3] do
where (x > 1)
while true do // error: can't use while (what would it mean?)
sortBy x
}
同樣:
query {
for x in [1;2;3] do
where (x > 1)
sortBy x
yield! ['a';'b';'c']
yield! ['x';'y';'z'] // error
}
這是一種模糊,因爲目前還不清楚第二yield!
是否是for
循環內或事後追加一組元素。
所以最好想查詢,查詢和序列的序列,儘管這兩種計算式的支持一些相同的操作。
一般情況下,查詢運營商定製工作要素的角度來看,這樣表達的東西像工會或級聯是尷尬的,因爲他們在處理整個集合,而不是單個元素。但是,如果你願意,你可以創建補充說,花了序列concat
運營商定製一個查詢構建器,雖然它可能會覺得有點不對稱:
open System.Linq
type QB() =
member inline x.Yield v = (Seq.singleton v).AsQueryable()
member inline x.YieldFrom q = q
[<CustomOperation("where", MaintainsVariableSpace=true)>]
member x.Where(q:IQueryable<_>, [<ProjectionParameter>]c:Expressions.Expression<System.Func<_,_>>) = q.Where(c)
[<CustomOperation("sortBy", MaintainsVariableSpace=true)>]
member x.SortBy(q:IQueryable<_>, [<ProjectionParameter>]c:Expressions.Expression<System.Func<_,_>>) = q.OrderBy(c)
[<CustomOperation("select")>]
member x.Select(q:IQueryable<_>, [<ProjectionParameter>]c:Expressions.Expression<System.Func<_,_>>) = q.Select(c)
[<CustomOperation("concat")>]
member x.Concat(q:IQueryable<_>, q') = q.Concat(q')
member x.For(q:IQueryable<'t>, c:'t->IQueryable<'u>) = q.SelectMany(fun t -> c t :> seq<_>) // TODO: implement something more reasonable here
let qb = QB()
qb {
for x in ([5;2;0].AsQueryable()) do
where (x > 1)
sortBy x
select x
concat ([7;8;9].AsQueryable())
} |> Seq.toList
來源
2015-10-20 16:30:29
kvb
我已經知道如何「的毗連/聯盟」都查詢,這更多的是一個哲學問題。既然它已經可以完成了,爲什麼不能用傳統的'yield!'在其他計算表達式中使用,比如'Seq'和'List'? – Luiso