matcher: 'a -> 'b -> bool
ACCEPT: matcher
REJECT: matcher
CHECK_FOR: char -> matcher
THEN: matcher * matcher -> matcher
ORELSE: matcher * matcher -> matcher
REPEAT: matcher -> matcher
val REJECT = fn cs => fn k => false
val ACCEPT = fn cs => fn k => k cs
fun CHECK_FOR a = fn cs => fn k -> (case cs of [] => false | c::cs' => a = c and k cs')
fun THEN (m1, m2) cs k = ml cs (fn cs' => m2 cs' k)
fun ORELSE (m1, m2) cs k = ml cs k orelse m2 cs k
fun REPEAT m cs k = k cs orelse m cs (fn cs' => cs <> cs' andalso REPEAT m cs' k)
Implementing match
(*match: regexp -> matcher*)
fun match (Char a) = CHECK_FOR a
| match One = ACCEPT
| match Zero = REJECT
| match (Times (r1, r2)) = THEN (match r1, match r2)
| match (Plus (r1, r2)) = ORELSE (match r1, match r2)
| match (Star r) = REPEAT (match r)
(*accept: regexp -> string -> bool*)
fun accept r: string -> bool
= let val m = match r
in fun s => m (String.explode s) List.null
end
val f = accept (regexp)
success continuation that takes failure as an argument -> give success continuation ability to fail
(*find: int tree -> (int -> (unit -> 'a) -> 'a) -> (init -> 'a) -> 'a*)
fun find Empty sk fk = fk ()
| find (Node (l, x, r)) sk fk = (let
fun fcnew () = find l sk (fn () => find r sk fk)
in
if x mod 2 = 0 then sk x fcnew else fcnew ()
end)
fun findone T = find T (fn x => fn _ => SOME x) (fn () => NONE)
fun findall T = find T (fn x => fn f => x::f) (fn () => [])
fun count T = find T (fn _ => fn f => 1 + f()) (fn () => 0)
Table of Content