Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>f# has two common associative data structures:</p> <p>The one you are most used to, the mutable Dictionary which it inherits that's to it's presence in the BCL and uses a hashtable under the hood.</p> <pre><code>let dict = new System.Collections.Generic.Dictionary&lt;string,int&gt;() dict.["everything"] &lt;- 42 </code></pre> <p>The other is known as <a href="http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/fsharp.core/microsoft.fsharp.collections.map.html" rel="nofollow noreferrer">Map</a> and is, in common functional style, immutable and implemented with binary trees.</p> <p>Instead of operations that would change a Dictionary, maps provide operations which return a new map which is the result of whatever change was requested. In many cases, under the hood there is no need to make an entirely new copy of the entire map, so those parts that can be shared normally are. For example:</p> <pre><code>let withDouglasAdams = Map.add "everything" 42 Map.empty </code></pre> <p>The value <code>withDouglasAdams</code> will remain forever as an association of "everything" to 42. so if you later do:</p> <pre><code>let soLong = Map.remove "everything" withDouglasAdams </code></pre> <p>Then the effect of this 'removal' is only visible via the <code>soLong</code> value.</p> <p>F#'s Map is, as mentioned, implemented as a binary tree. Lookup is therefore O(log n) whereas a (well behaved) dictionary should be O(1). In practice a hash based dictionary will tend to outperform the tree based one in almost all simple (low number of elements, low probability of collision) as such is commonly used. That said the immutable aspect of the Map may allow you to use it in situations where the dictionary would instead require more complex locking or to write more 'elegant' code with fewer side effects and thus it remains a useful alternative.</p> <p>This is not however the source of your problem. The dict 'operator' returns an explicity immutable <code>IDictionary&lt;K,T&gt;</code> implementation (despite not indicating this in it's documentation).</p> <p>From <em>fslib-extra-pervasives.fs</em> (note also the use of options on the keys):</p> <pre><code>let dict l = // Use a dictionary (this requires hashing and equality on the key type) // Wrap keys in an Some(_) option in case they are null // (when System.Collections.Generic.Dictionary fails). Sad but true. let t = new Dictionary&lt;Option&lt;_&gt;,_&gt;(HashIdentity.Structural) for (k,v) in l do t.[Some(k)] &lt;- v let d = (t :&gt; IDictionary&lt;_,_&gt;) let c = (t :&gt; ICollection&lt;_&gt;) let ieg = (t :&gt; IEnumerable&lt;_&gt;) let ie = (t :&gt; System.Collections.IEnumerable) // Give a read-only view of the dictionary { new IDictionary&lt;'key, 'a&gt; with member s.Item with get x = d.[Some(x)] and set (x,v) = raise (NotSupportedException( "This value may not be mutated")) ... </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload