fsharp
fsharp copied to clipboard
LINQ producing incorrect runtime result with boxed ValueOptions
You cannot compare value-options directly due to #13370 Boxing them causes the LINQ compiles but does incorrect runtime result:
Repro steps, actual behaviour
let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query {
for d1 in datasource1 do
for d2 in datasource2 do
where (box(ValueSome(d1)) = box(d2))
select (d1, d2)
} |> Seq.toList;;
// val it: (int * int voption) list = []
// Empty???
The same issue can be observed with Some
:
let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query {
for d1 in datasource1 do
for d2 in datasource2 do
where (Some(ValueSome(d1)) = Some(d2))
select (d1, d2)
} |> Seq.toList;;
// val it: (int * int voption) list = []
// Empty???
Expected behavior
If I change the =
to Equals, then it produces a different result:
open System.Linq
let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query {
for d1 in datasource1 do
for d2 in datasource2 do
where (ValueSome(d1).Equals(d2))
select (d1, d2)
} |> Seq.toList;;
// val it: (int * int voption) list = [(1, ValueSome 1); (2, ValueSome 2)]
Or with boxed:
open System.Linq
let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query {
for d1 in datasource1 do
for d2 in datasource2 do
where (box(ValueSome(d1)).Equals(box(d2)))
select (d1, d2)
} |> Seq.toList;;
I expect this will do a method-call instead of Expression.Equals in the LINQ-tree. Which may cause the sub-expressions not visited by LINQ for any kind of transpilation, and that's why this is not a workaround. Is there maybe something wrong with StructuralComparison when using Linq?
Known workarounds
None.
Related information
Environment tested with:
- Operating system Win 11
- .NET Runtime kind (.NET Core, .NET Framework, Mono) 6.0.301
- F# 6.0.5
- Editing Tools: Visual Studio 2022
I think this is fixed by https://github.com/dotnet/fsharp/pull/11681
This is indeed fixed by #11681