Difference between revisions of "Chained Dictionary Assignment"
Line 104: | Line 104: | ||
==structure SingleChainedDictionary== | ==structure SingleChainedDictionary== | ||
One can imagine the utility of having a simple Dictionary without the overhead of a HashTable. Perhaps, the number of anticipated entries is small. Perhaps, its performance is not critical. Maybe the client has a lot of tasks on his or her plate and simply does not feel like creating a custom hash function for their type. Whatever the reason, it seems like a reasonable implementation of Dictionary to provide. | One can imagine the utility of having a simple Dictionary without the overhead of a HashTable. Perhaps, the number of anticipated entries is small. Perhaps, its performance is not critical. Maybe the client has a lot of tasks on his or her plate and simply does not feel like creating a custom hash function for their type. Whatever the reason, it seems like a reasonable implementation of Dictionary to provide. | ||
− | |||
− | |||
=== signature SINGLE_CHAINED_DICTIONARY === | === signature SINGLE_CHAINED_DICTIONARY === | ||
Line 117: | Line 115: | ||
=== structure TypeHolder === | === structure TypeHolder === | ||
+ | Change the definition of type (''k,'v) dictionary to support SingleChainedDictionary. | ||
<nowiki>structure TypeHolder = struct | <nowiki>structure TypeHolder = struct | ||
Line 122: | Line 121: | ||
type (''k,'v) dictionary = unit | type (''k,'v) dictionary = unit | ||
end</nowiki> | end</nowiki> | ||
+ | |||
+ | [[File:Single_chained_dictionary.svg|400px]] | ||
+ | |||
+ | === structure TypeHolder === | ||
+ | <nowiki>structure SingleChainHasEntries = HasEntriesFn (struct | ||
+ | type (''k,'v) dictionary = (''k,'v) TypeHolder.dictionary | ||
+ | fun entries(dict : (''k,'v) dictionary) : (''k*'v) list = | ||
+ | raise Fail "NotYetImplemented" | ||
+ | end)<nowiki> | ||
+ | ====entries==== | ||
+ | |||
=== structure SingleChainHasChaining === | === structure SingleChainHasChaining === | ||
Line 140: | Line 150: | ||
setChainOfAllEntries(dict, nextEntries) | setChainOfAllEntries(dict, nextEntries) | ||
end)</nowiki> | end)</nowiki> | ||
+ | |||
+ | ====getChainOfAllEntries==== | ||
+ | |||
+ | ====setChainOfAllEntries==== | ||
=== create === | === create === |
Revision as of 19:54, 28 February 2022
Contents
Motivation
In this and the follow up Sorted Dictionary studio, you will build three implementations of a dictionary. Each will be a persistent, mutable data structure, so you can expect to use the ref feature of SML, either directly or via the mutable Array structure.
Background
SML
ref
fun get_value_at_reference(reference : 'a ref) : 'a = !reference fun set_value_at_reference(reference : 'a ref, next_value : 'a) : 'a = let val previous_value = !reference val _ = reference := next_value in previous_value end (* alternate version fun set_value_at_reference(reference : 'a ref, next_value : 'a) : 'a = let val previous_value = !reference in ( reference := next_value ; previous_value ) end *)
Mutable Array
HashTable
Code To Investigate
signature Dictionary
signature DICTIONARY = sig type (''k,'v) dictionary val get : ((''k,'v) dictionary *''k) -> 'v option val put : ((''k,'v) dictionary *''k *'v) -> 'v option val remove : ((''k,'v) dictionary *''k) -> 'v option val entries : (''k,'v) dictionary -> (''k*'v) list val keys : (''k,'v) dictionary -> ''k list val values : (''k,'v) dictionary -> 'v list end
get
Behaves much like java.util.Map<K,V>'s get(key) method except instead of returning null or the associated value, it returns an option.
put
Behaves much like java.util.Map<K,V>'s put(key,value) method except instead of returning null or the previously associated value, it returns an option.
remove
Behaves much like java.util.Map<K,V>'s remove(key) method except instead of returning null or the previously associated value, it returns an option.
entries
Behaves much like java.util.Map<K,V>'s entrySet() method.
keys
Behaves much like java.util.Map<K,V>'s keySet() method.
values
Behaves much like java.util.Map<K,V>'s values() method.
Code To Implement
functor HasEntriesFn
Each implementation of dictionary can reuse the same functions which given a list of entries produce the keys and values. functor HasEntriesFn
accepts a signature parameter which defines an entries function to support keys
and values
functions.
functor HasEntriesFn (HasEntriesParameter : sig type (''k,'v) dictionary val entries : (''k,'v) dictionary -> (''k*'v) list end) : HAS_ENTRIES = struct
keys
One of List's higher order functions can be useful here. Which one is it?
fun keys(dict : (''k,'v) dictionary) : ''k list = raise Fail "NotYetImplemented"
values
One of List's higher order functions can be useful here. Which one is it?
fun values(dict : (''k,'v) dictionary) : 'v list = raise Fail "NotYetImplemented"
functor HasChainingFn
One can anticipate that separate structures for SingleChainedDictionary
and HashedDictionary
have potential for code resuse. By parameterizing
functor HasChainingFn
with getChainOfEntriesForKey
and setChainOfEntriesForKey
we can implement get
, put
, and remove
.
functor HasChainingFn (HasChainingParameter : sig
type (''k,'v) dictionary
val getChainOfEntriesForKey : ((''k,'v) dictionary * ''k) -> (''k*'v) list
val setChainOfEntriesForKey : ((''k,'v) dictionary * ''k * (''k*'v) list) -> unit
end) : HAS_CHAINING = struct
get
put
remove
structure SingleChainedDictionary
One can imagine the utility of having a simple Dictionary without the overhead of a HashTable. Perhaps, the number of anticipated entries is small. Perhaps, its performance is not critical. Maybe the client has a lot of tasks on his or her plate and simply does not feel like creating a custom hash function for their type. Whatever the reason, it seems like a reasonable implementation of Dictionary to provide.
signature SINGLE_CHAINED_DICTIONARY
We can see that signature SINGLE_CHAINED_DICTIONARY
includes DICTIONARY
and adds a create
function.
structure SingleChainedDictionary :> SINGLE_CHAINED_DICTIONARY
signature SINGLE_CHAINED_DICTIONARY = sig include DICTIONARY
val create : unit -> (''k,'v) dictionary
end
structure TypeHolder
Change the definition of type (k,'v) dictionary to support SingleChainedDictionary.
structure TypeHolder = struct
(* TODO: replace unit with the type you decide upon *)
type (''k,'v) dictionary = unit
end
structure TypeHolder
structure SingleChainHasEntries = HasEntriesFn (struct
type (''k,'v) dictionary = (''k,'v) TypeHolder.dictionary
fun entries(dict : (''k,'v) dictionary) : (''k*'v) list =
raise Fail "NotYetImplemented"
end)<nowiki>
====entries====
=== structure SingleChainHasChaining ===
<nowiki>structure SingleChainHasChaining = HasChainingFn (struct
type (''k,'v) dictionary = (''k,'v) TypeHolder.dictionary
fun getChainOfAllEntries(dict : (''k,'v) dictionary) : (''k*'v) list =
raise Fail "NotYetImplemented"
fun setChainOfAllEntries(dict : (''k,'v) dictionary, nextEntries : (''k*'v) list) : unit =
raise Fail "NotYetImplemented"
fun getChainOfEntriesForKey(dict : (''k,'v) dictionary, key : ''k) : (''k*'v) list =
getChainOfAllEntries(dict)
fun setChainOfEntriesForKey(dict : (''k,'v) dictionary, key : ''k, nextEntries : (''k*'v) list) : unit =
setChainOfAllEntries(dict, nextEntries)
end)
getChainOfAllEntries
setChainOfAllEntries
create
fun create() : (''k,'v) dictionary =
raise Fail "NotYetImplemented"
Hashtable Implementation
signature HASHED_DICTIONARY = sig include DICTIONARY
type ''k hash_function = ''k -> int
val create_hashed : (int * ''k hash_function) -> (''k,'v) dictionary
end
Testing
file: sml run_chained_testing.sml
in folder: src/test/sml/dictionary/chained
Pledge, Acknowledgments, Citations
file:
studio-dictionary-pledge-acknowledgments-citations.txt
More info about the Honor Pledge