where 条件下的元组

Tuples in where condition

鉴于在 F#

Tuples have an automatically defined equality operation

因此

let myQueryable = [| (1, 1); (2,2)|].AsQueryable()
let check =
    query {
        for x in myQueryable do
        } |> Seq.where(fun x -> x = (2,2))

{(2,2)},那为什么

let check =
        query {
            for x in myQueryable do
            where(x = (2, 2))
            }

Empty吗?

您可能 System.Linq 打开了。

以下returns (2,2) 对我来说两种情况:

//open System
//open System.Linq

let myQueryable = [| (1, 1); (2,2) |] //.AsQueryable()
let check =
    query {
            for x in myQueryable do
            select x
          } |> Seq.where(fun x -> x = (2,2))

check //val it : seq<int * int> = seq [(2, 2)]
let check' =
        query {
            for x in myQueryable do
            where (x = (2, 2)) 
            select x
            }

check' //val it : seq<int * int> = seq [(2, 2)] 

因此在 IQueryable 中,这种结构等式不成立。我不知道是不是因为 IQueryable 类型,即它变成了引用相等性,或者 where 被重新定义,或者是一个可能的错误。

C# System.Tuple 和 F# 引用元组之间似乎存在兼容性问题。

有趣的是,C# 7 和 F# 4.1 之间的兼容性问题似乎已经解决,新的 ValueTuple 等同于 F# 结构元组。

let myQueryableNew = [| ValueTuple.Create(1, 1); ValueTuple.Create(2,2) |].AsQueryable()
let resultFSharp1 =
    query {
            for x in myQueryableNew do
          } |> Seq.where(fun x -> x = ValueTuple.Create(2,2))

let resultFSharp2 =
        query {
            for x in myQueryableNew do
            where (x.Equals(ValueTuple.Create(2, 2))) 
            }

顺便说一句,另请注意新类型具有更连贯的默认值(在这种情况下相关issue

let testDefault =
        query {
            for x in myQueriable1 do
            where (x.Equals(ValueTuple.Create(1, 2))) 
            select x
            headOrDefault
            }