signature CELL = sig type 'a cell val cell : 'a -> 'a cell val get : 'a cell -> 'a val put : 'a cell * 'a -> unit val stop : 'a cell -> unit end; structure Cell :> CELL = struct datatype 'a request = GET | PUT of 'a | STOP datatype 'a cell = CELL of ('a request) CML.chan * 'a CML.chan fun cell x = let val reqCh = CML.channel () val replyCh = CML.channel () fun loop x = (case (CML.recv reqCh) of GET => (CML.send (replyCh, x); loop x) | PUT(x') => loop x' | STOP => CML.exit ()) in CML.spawn (fn () => loop x); CELL (reqCh, replyCh) end fun get (CELL(reqCh, replyCh)) = ( CML.send (reqCh, GET); CML.recv (replyCh) ) fun put (CELL(reqCh, replyCh), x) = CML.send (reqCh, PUT(x)) fun stop (CELL(reqCh, replyCh)) = CML.send (reqCh, STOP) end; structure Cell' :> CELL = struct datatype 'a cell = CELL of 'a CML.chan * 'a CML.chan * unit CML.chan fun cell x = let val getCh = CML.channel () val putCh = CML.channel () val stopCh = CML.channel () fun loop x = CML.select [CML.wrap (CML.sendEvt (getCh, x), fn () => loop x), CML.wrap (CML.recvEvt putCh, fn x' => loop x'), CML.wrap (CML.recvEvt stopCh, fn () => CML.exit ())] in CML.spawn (fn () => loop x); CELL (getCh, putCh, stopCh) end fun get (CELL(getCh, _, _)) = CML.recv getCh fun put (CELL(_, putCh, _), x) = CML.send (putCh, x) fun stop (CELL(_, _, stopCh)) = CML.send (stopCh, ()) end; (* U.apply (fn () => let val c = Cell.cell 3 val _ = Cell.put (c, 4) val r = Cell.get c val _ = Cell.stop (c) in r end) (); U.apply (fn () => let val c = Cell'.cell 3 val _ = Cell'.put (c, 4) val r = Cell'.get c val _ = Cell'.stop (c) in r end) (); *)