Difference between revisions of "Chained Dictionary Assignment"

From CSE425S Wiki
Jump to navigation Jump to search
m (Dennis.cosgrove moved page Dictionary Assignment to Chained Dictionary Assignment)
Line 66: Line 66:
 
     raise NotYetImplemented</nowiki>
 
     raise NotYetImplemented</nowiki>
  
=ListOfEntries (Optional But Encouraged)=
+
=HasEntriesFn=
While it is not required, both the SingleList and Hashtable implementations will have a lot of overlap.  Building the common functionality will allow you to reuse this code.  Further, some students have reported the separation helping with wrangling the references in the dictionaries.
 
 
 
 
  <nowiki>
 
  <nowiki>
    fun list_get(entries : (''k*'v) list, key : ''k) : 'v option =
+
functor HasEntriesFn (HasEntriesParameter : sig
        raise NotYetImplemented
+
type (''k,'v) dictionary
 
+
val entries : (''k,'v) dictionary -> (''k*'v) list
    fun list_put(entries : (''k*'v) list, key : ''k, value : 'v) : 'v option * (''k * 'v) list=
+
end) : HAS_ENTRIES = struct
        raise NotYetImplemented
+
open HasEntriesParameter
 
 
    fun list_remove(entries : (''k*'v) list, key : ''k) : 'v option * (''k * 'v) list =
 
        raise NotYetImplemented</nowiki>
 
  
 +
    fun keys(dict : (''k,'v) dictionary) : ''k list =
 +
        (* <SOLUTION> *)
 +
        if true
 +
        then
 +
        List.map (fn(key,_)=>key) (entries(dict))
 +
        else (* </SOLUTION> *)raise Fail "NotYetImplemented"
  
'''NOTE: You may change this file. For example, if you decide to go with a mutable key-value pair for your single-list and hash dictionaries, feel free to change this module to match what you need.'''
+
    fun values(dict : (''k,'v) dictionary) : 'v list =
 +
        (* <SOLUTION> *)
 +
        if true
 +
        then
 +
        List.map (fn(_,value)=>value) (entries(dict))
 +
        else (* </SOLUTION> *)raise Fail "NotYetImplemented"
 +
end</nowiki>
  
 
=SingleList Implementation=
 
=SingleList Implementation=

Revision as of 15:28, 28 February 2022

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

Refs and Arrays


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
*)

Dictionary

Signature

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

Spec

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.


DictionaryUtils

All three implementations of dictionary can reuse the same functions which given a list of entries produce the keys and values.

One of List's higher order functions can be useful here. Which one is it?

fun entries_to_keys(entries : (''k*'v) list) : ''k list = 
    raise NotYetImplemented

fun entries_to_values(entries : (''k*'v) list) : 'v list =
    raise NotYetImplemented

HasEntriesFn

functor HasEntriesFn (HasEntriesParameter : sig
	type (''k,'v) dictionary
	val entries : (''k,'v) dictionary -> (''k*'v) list
end) : HAS_ENTRIES = struct
	open HasEntriesParameter

    fun keys(dict : (''k,'v) dictionary) : ''k list = 
        (* <SOLUTION> *)
        if true
        then
	        List.map (fn(key,_)=>key) (entries(dict))
        else (* </SOLUTION> *)raise Fail "NotYetImplemented"

    fun values(dict : (''k,'v) dictionary) : 'v list = 
        (* <SOLUTION> *)
        if true
        then
	        List.map (fn(_,value)=>value) (entries(dict))
        else (* </SOLUTION> *)raise Fail "NotYetImplemented"
end

SingleList Implementation

signature SINGLE_LIST_DICTIONARY = sig include DICTIONARY
    val create : unit -> (''k,'v) dictionary
end

Hashtable Implementation

Hash table

Hash table 5 0 1 1 1 1 1 LL.svg

SML Array Structure

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 renovated_unit_test_single_list_and_hashed.sml

in folder: src/test/sml/dictionary/single_list_and_hashed

Pledge, Acknowledgments, Citations

file: studio-dictionary-pledge-acknowledgments-citations.txt

More info about the Honor Pledge