Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why F#'s default set collection is sorted while C#'s isn't?

When migrating from a C# world to an F# (the most idiomatic possible) mindset, I've found this interesting difference.

In C#'s OOP&mutable world, the default set collection seems to be HashSet, which seems to be not sorted by default (because the comparer that it accepts is just for equality); while if you wanted a sorted one you would have to use SortedSet.

However in F#'s world, the basic set is already sorted because it requires the element type used to implement equality and comparison. Any specific reason for this? Why not having an unordered set in the main collections for this language?

As a side-note, I'm wondering if it'd be possible to have a set collection that didn't allow duplicates, but that had a preference over certain elements when discarding some elements as duplicates. Example: a record { Name: string; Flag: Option<unit> } so that when inserting { Name = "foo"; Flag = None } and later { Name = "foo"; Flag = Some() } it ended up containing only the latter element (because Flag is present).

like image 693
knocte Avatar asked Aug 07 '19 11:08

knocte


People also ask

Is F-22 the best fighter jet?

The Powerful F-22 Military Fighter JetThe F-22 may be the most efficient air superiority fighter, but that doesn't mean it isn't capable enough in other roles like ground attacks and electronic warfare. Lockheed Martin equips the aircraft with the most modern systems and features a military jet could carry.

Why is F-22 so good?

With advanced sensors, the fighter can see threats from far away; with its stealthy shape and materials, it can sneak up on those threats undetected; with its supercruise ability, it can sneak faster than threats can react; and, with its thrust vectoring capability, it can out-dance any opponent within visual range.

Was the F-14 a good plane?

The F-14 embodied the broadest capabilities of any airplane ever designed for and flown in combat. It was a tactical airplane with strategic capabilities. Genius. For today's mission we won't compare the Tomcat /AIM-54 missile combination to the Flanker /AA-10C.

Why is F-35 so good?

Designed from the ground up to prioritize low-observability, the F-35 may be the stealthiest fighter in operation today. It uses a single F135 engine that produces 40,000 lbs. of thrust with the afterburner engaged, capable of pushing the sleek but husky fighter to speeds as high as Mach 1.6.


1 Answers

F# Set happens to be sorted, but it's more of an implementation detail resulting from the choice of the underlying data structure and should not generally be relied upon.

F# sets and maps are based on a variant of AVL tree and that structure happens to maintain the invariant that elements stored in the tree are sorted. The reason why it requires comparison constraint is because lookup in this tree structure depends on direct comparisons between elements to select the subtree that gets traversed.

The selling point of these structures however is the fact that they can be used to implement reasonably efficient, immutable versions of maps and sets cheaply, and that's what F# needed at a time where the wider .NET platform didn't offer any alternatives.

Note that this is not the only viable choice in this context and JVM functional languages like Clojure or Scala opted for a different data structure as the base for their maps - hash array mapped trie - which is also immutable and persistent, arguably more complex to implement, arguably more efficient for larger collection sizes, but happens to store elements unordered. Unlike AVL trees, the traversal of the tree is based on hashes, so comparison constraint is not required.

So if you already know that your priority is immutability, a sorted set is actually easier to implement than an unsorted set.

like image 174
scrwtp Avatar answered Sep 20 '22 13:09

scrwtp