Я работаю над чем-то для задачи обработки изображений (здесь это не очень актуально), и я наткнулся на поведение типа Option F #, которое меня удивило в отношении выполнения сравнений больше (>). Я не смог найти ничего, что прямо объясняло бы то, что я должен ожидать (подробнее об этом ниже) в переполнении стека, документах F # или более широкой сети.
Конкретная часть, на которую я смотрю, выглядит примерно так:
let sort3Elems (arr: byte option []) =
if arr.[0] > arr.[1] then swap &arr.[0] &arr.[1]
if arr.[1] > arr.[2] then swap &arr.[1] &arr.[2]
if arr.[0] > arr.[1] then swap &arr.[0] &arr.[2]
, где я буду передавать массивы из четырех байтов (если вам интересно, почему это выглядит странно и сверхфункционально, сейчас я намеренно пытаюсь повторно реализовать реализацию на нефункциональном языке алгоритм в учебнике). Я ожидал, что это приведет к ошибке компилятора, когда он будет жаловаться, что параметры не могут быть напрямую сопоставлены. К моему удивлению, это скомпилировано нормально. Заинтригованный, я протестировал его в F # Interactive, результаты которого выглядят примерно так:
let arr: byte option [] = Array.zeroCreate 4;;
val arr : byte option [] = [|None; None; None; None|]
> arr.[0] <- Some(127uy);;
val it : unit = ()
> arr.[2] <- Some(55uy);;
val it : unit = ()
> arr.[0] > arr.[2];;
val it : bool = true
> arr.[0] < arr.[2];;
val it : bool = false
> arr.[0] < arr.[1];;
val it : bool = false
> arr.[0] > arr.[1];;
val it : bool = true
> arr.[2] > arr.[1];;
val it : bool = true
> arr.[3] > arr.[1];;
val it : bool = false
> arr.[3] < arr.[1];;
val it : bool = false
> arr.[3] > arr.[1];;
val it : bool = false
Мне кажется, что, по сути, операторы сравнения всегда должны возвращать true (false), когда спрашивают, является ли Some больше (меньше), чем None, два None всегда возвращают false, а два Some одного и того же содержащегося типа сравнивают содержащий значения (при условии, что их можно сравнить, я представляю). Это имеет смысл, хотя я был удивлен.
Желая подтвердить это, я попытался отследить что-то, что могло бы объяснить поведение, которое я должен ожидать, но я не смог найти ничего, что отвечало бы этой теме. Страница опций в Руководстве по MS F # не упоминает об этом, и я не смог найти ничего в таких местах, как F #, для развлечения и получения прибыли. Мне даже не удалось найти страницу о Option где-либо в документации MS API ... Просмотр источника для Option в репозитории F # GitHub ничего мне не говорит. Лучшее, что я смог найти, было сообщение в блоге Дона Сайма от лет назад, которое фактически не отвечало на мой вопрос. Было несколько вопросов о переполнении стека, в которых обсуждались темы, относящиеся к операторам сравнения или типам Option, но я не нашел ничего, что касалось комбинации этих двух.
Итак, мой вопрос заключается в том, дает ли выполнение сравнений типа «больше» или «меньше» тип Option, результаты, о которых я размышлял выше? Я предполагаю, что это достаточно распространенное знание среди программистов на F #, но для меня это было новостью. Как вспомогательный / связанный вопрос, знает ли кто-нибудь, куда я мог бы / должен был обратиться за дополнительной информацией? Спасибо.