F#奇怪的模式匹配结果

F#奇怪的模式匹配结果,f#,F#,我正在编写一个二进制搜索实现。我遇到的问题是模式匹配块 此代码使用模式匹配返回奇怪的结果。第一个匹配块没有返回我期望的结果。它警告我,(u,u)永远无法到达 let binSearch (item:double) (arr:list<double>) = let rec binSearchRec first last = if first > last then let lastIndex = arr.Length-1

我正在编写一个二进制搜索实现。我遇到的问题是模式匹配块

此代码使用模式匹配返回奇怪的结果。第一个匹配块没有返回我期望的结果。它警告我,
(u,u)
永远无法到达

let binSearch (item:double) (arr:list<double>) =
    let rec binSearchRec first last =
        if first > last then
            let lastIndex = arr.Length-1
            let len = arr.Length
            match (first, last) with
            | (0, -1) -> System.String.Format("ITEM SMALLER THAN {0}", arr.[0])
            | (len, lastIndex) -> System.String.Format("ITEM BIGGER THAN {0}", arr.[lastIndex])
            | (_,_) -> System.String.Format("IN BETWEEN {0} AND {1}", arr.[last], arr.[first])
        else
            let mid = (first+last)/2
            match item.CompareTo(arr.[mid]) with
            | -1 -> binSearchRec first (mid-1)
            | 0 -> "CONTAINS"
            | 1 -> binSearchRec (mid+1) last
    binSearchRec 0 (arr.Length-1)
我不明白这个匹配调用与这个if-else调用有何不同,也不明白为什么这个调用工作得很好,但模式匹配块却不行


一个奇怪的结果是,在
(len,lastIndex)
匹配中打印len会在匹配中返回错误的数字。对于长度为3的数组,match语句之前的
len打印将显示3,而match语句内部的打印将显示1。

match表达式中的一个分支正在创建与现有符号的新绑定

| (len, lastIndex) -> ...
所以这个分支与其他所有情况都匹配

如果要在匹配表达式中匹配与现有值的内容,则可以在对其进行分类时使用:

| (a, b) when a = len && b = lastIndex -> ...
另一种选择是将len和lastIndex声明为文本,以便在模式匹配中使用它们,但在您的情况下这似乎并不自然

[<Literal>]
let len = arr.Length
[]
设len=arr.长度

无论如何,在这种情况下不能使用Literal,您只能将其用于Literal值,而不能用于运行时值,如
arr.Length
[<Literal>]
let len = arr.Length