I'm working on something for an image processing task (it's not greatly relevant here), and I stumbled across behaviour of F#'s Option type that surprised me, regarding performing greater than (>) comparisons. I couldn't find anything that directly explained what I should expect (more on that below) on Stack Overflow, the F# docs or the wider web.
The specific part I am looking at looks something like:
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]
where I will be passing in arrays of four byte options (if you're wondering why this looks weird and is super-unfunctional, right now I'm deliberately trying to re-implement the non-functional-language implementation of an algorithm in a textbook). I was expecting this to cause a compiler error, where it would complain that the options couldn't be directly compared. To my surprise, this compiled fine. Intrigued, I tested it out in F# Interactive, the results of which look something like the below:
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
It seems to me that essentially the comparison operators must always return true (false) when asking whether a Some is greater (less) than a None, two Nones always return false, and two Somes of the same contained type compare the contained values (assuming that they can be compared I imagine). This makes sense, though I was surprised.
Wanting to confirm this, I attempted to track something down that would explain the behaviour I should expect, but I couldn't find anything that addressed the point. The Option page in the MS F# Guide docs doesn't make any mention of it, and I couldn't find anything in places like F# for fun and profit. I couldn't even manage to find a page about Option anywhere in the MS API docs... Looking at the source for Option in the F# GitHub repo doesn't tell me anything. The best I could find was a blog post by Don Syme from years ago, which didn't actually answer my question. There were a smattering of Stack Overflow questions that discussed topics to do with the comparison operators or Option types, but I didn't find anything that dealt with the combination of the two.
So, my question is, does performing greater than/less than comparisons on the Option type return the results I have speculated about above? I'm guessing that this is reasonably common knowledge amongst F# programmers, but it was news to me. As a sub-/related question, does anyone know where I could/should have looked to for more information? Thanks.