Я пишу реализацию бинарного поиска. У меня проблема с блоком соответствия шаблонов.F # Weird pattern matching result
Этот код с использованием сопоставления образцов возвращает странные результаты. Первый блок соответствия не возвращает то, что я ожидаю. Он предупреждает меня, что (_,_)
так и не был достигнут.
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)
Замена, что первый match (first, last)
вызов с этим, если-то еще альтернативы работает хорошо:
if first = 0 && last = -1 then
System.String.Format("ITEM SMALLER THAN {0}", arr.[0])
else if first = len && last = lastIndex then
System.String.Format("ITEM BIGGER THAN {0}", arr.[lastIndex])
else
System.String.Format("IN BETWEEN {0} AND {1}", arr.[last], arr.[first])
Я не понимаю, как этот вызов матч отличается от этого, если-то еще звонок, и почему это хорошо работает но блок сопоставления шаблонов не работает.
Странным результатом является то, что печать len в матче (len, lastIndex)
возвращает неправильные номера внутри матча. Для массива длины три оттиск len
перед оператором матча покажет 3, тогда как печать внутри матча покажет 1.
Literal не может использоваться в этом случае в любом случае, вы можете использовать его только для, ну, буквальных значений, а не для значений времени исполнения, таких как 'arr.Length'. – Tarmil