ref : 'a -> 'a ref
!: 'a ref -> 'a
:s = 'a ref * 'a -> unit
Reference Cell: t ref
is a type iff t
is a type
is a value
contain a (evaluated) value
be able to
ref e : t ref
is e : t
you can think of ref
as a constructor, can be used in pattern matching
ref v
= reference cell containing value v, they might be the same or different cell
!
pronounce as bang
!e : t
if e: f ref
and if e => ref v
then !e => v
e1 := e2 : unit
if e1 : t ref
and e2 : t
(notice the two types has to be the same)
it changes the content of e1
to e2
Mutation
I/O
raising exception
declaring exception
callcc
| Type | Functional / Persistent | Imperative / Ephemeral | | Sequential | fine | Impure Functional | | Parallel | happy | Concurrency |
(* whether x is a member of l*)
fun member x l = List.exists (fn z => x = z) l
fun reachable g (x, y)
= let
val visited = ref []
fun dfs n = n = y orelse
(not(member n (!visited))
andalso (visited := n::!visited;
List.exists dfs (g n) ))
in
dfs x
end
Benign effect: you can't tell from outside the program if you have mutation
fun delay (d: unit -> 'a front) : 'a stream
= let
val answer = ref NONE
fun d' () = (case !answer of
NONE => let val x = let val x = d () in (answer := SOME x; x) end
| SOME x => x)
in
stream d'
end
Without branching
fun delay d
= let
val cell : (unit -> 'a) ref = ref d (* don't care d, for typing purpose *)
fun memo () = let val r = d () in (cell := (fn () => f); r) end
val () = cell := memo
in
Stream (fn () => !cell ())
end
Table of Content