Created
December 2, 2011 22:55
-
-
Save philtomson/1425225 to your computer and use it in GitHub Desktop.
Using the Functorial interface to HashTbl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* ( 'cs, 'conditions, 'actions, 'ns) *) | |
(* given a current state (cs) | |
* and condition - get the resulting actions and next state ('ns) *) | |
type 'a state = State of 'a ;; | |
type ('cs, 'cond, 'action, 'ns) st_entry = ST_Entry of ('cs * 'cond * 'action * 'ns);; | |
type state_list = st_entry list ;; | |
type ('cs, 'cond) st_cond = State_Cond of ('cs * 'cond) ;; | |
type ('action, 'ns) st_action_ns = Action_NS of ('action * 'ns);; | |
module States = struct | |
(* FILL_WSH and FILL_RNS allow for different temps for wash | |
* and rinse *) | |
type t = FILL_WSH | WASH | EMPTY | FILL_RNS | RINSE | SPIN | STOP | |
end ;; | |
(* probably need something like "signals" that can be put into expressions | |
* which can be evaluated | |
*) | |
module Conditions = struct | |
(*TODO: condition expressions*) | |
end;; | |
(* define a state list (declarative) *) | |
let my_fsm = [(States.FILL_WSH, "full", "water_on", States.WASH); | |
(States.WASH, "10Minutes", "agitate", States.EMPTY); | |
(States.EMPTY, "empty", "drain", States.FILL_RNS); | |
(States.FILL_RNS, "full", "water_on", States.RINSE); | |
(States.RINSE, "10Minutes", "agitate", States.EMPTY); | |
(States.EMPTY, "empty", "drain", States.SPIN); | |
(States.SPIN, "5Minutes", "motor_on", States.STOP); | |
(States.STOP, "*", "motor_off", States.STOP); | |
];; | |
module ST_Table = Hashtbl.Make( | |
struct | |
type t = States.t | |
let equal = (=) | |
let hash = Hashtbl.hash | |
end | |
);; | |
(* | |
module ST_Table : | |
sig | |
type key = States.t | |
type 'a t | |
val create : int -> 'a t | |
val clear : 'a t -> unit | |
val copy : 'a t -> 'a t | |
val add : 'a t -> key -> 'a -> unit | |
val remove : 'a t -> key -> unit | |
val find : 'a t -> key -> 'a | |
val find_all : 'a t -> key -> 'a list | |
val replace : 'a t -> key -> 'a -> unit | |
val mem : 'a t -> key -> bool | |
val iter : (key -> 'a -> unit) -> 'a t -> unit | |
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b | |
val length : 'a t -> int | |
end | |
*) | |
let sh = ST_Table.create 5 ;; (* what if instead of '4' you could determine the number of options in States? *) | |
(* val sh : '_a ST_Table.t = <abstr> *) | |
(* now we build it from my_fsm list instead | |
ST_Table.add sh States.FILL ("full", States.WASH);; | |
ST_Table.add sh States.WASH ("after 10 minutes", States.EMPTY);; | |
ST_Table.add sh States.EMPTY ("empty", States.RINSE);; | |
ST_Table.add sh States.RINSE ("empty", States.SPIN);; | |
ST_Table.add sh States.SPIN ("after 5 minutes", States.STOP);; | |
*) | |
let _ = List.iter (fun (cs, cond, action, ns) -> ST_Table.add sh cs (cond, action, ns)) my_fsm;; | |
ST_Table.find_all sh States.FILL_WSH ;; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ah, thanks for explaining!