I have the following sample that finds the numbers in s1 that are not in s2.
let s1 = seq { 1..3 }
let s2 = seq { 3..4 }
s1
|> Seq.filter (fun x -> s2 |> Seq.forall (fun y -> x <> y))
|> Seq.iter (fun x -> printfn $"{x}")
This prints 1 and 2 as expected.
Can this also be expressed as a query expression?
>Solution :
First of all, I think your existing solution using filter
and forall
is perfectly fine and does not need to be converted to query expressions – those are great for SQL-like queries and querying databases, but I think they are often a bit unhelpful for basic sequence processing.
To answer your question, you can do this using a nested query
(as in the answer from Violet), but using the all
operation:
query {
for x in s1 do
where (query { for y in s2 do all (y > 0) })
select x }
This is really exactly the same as your original code – the outer query implements filter
and the nested query implements forall
. You could also freely combine the two:
query {
for x in s1 do
where (Seq.forall (fun y -> x <> y) s2)
select x }
Although I guess it gets a bit nicer if you turn s2
into a set first:
let s2set = set s2
query {
for x in s1 do
where (not (s2set.Contains x))
select x }