//
// Course: BU CAS CS 520
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
//

(* ****** ****** *)

fun findz
  (f: int -> int): int = loop (0) where {
  fun loop (i: int):<cloref1> int =
    if f (i) = 0 then i else loop (i+1)
  // end of [loop]
}

val poly1 = lam (x: int): int => (x + 10) * (x - 11)

val z1 = findz (poly1)

val () = printf ("z1 = %i\n", @(z1))

(* ****** ****** *)

// abst@ype ans_t = int
typedef ans_t = int
typedef cont (a: t@ype) = a -<cloref1> ans_t

val kpoly1 =
  lam (x: int, k: cont int): ans_t => k ((x + 10) * (x - 11))
// end of [kpoly1]
// kpoly1 : (int, cont int) -> ans_t

fun kfindz
  (kf: (int, cont int) -> ans_t, k: cont int): ans_t = let
  fun kloop (i: int, k: cont int):<cloref1> int =
    kf (i, lam res => if res = 0 then k (i) else kloop (i+1, k))
  // end of [loop]
in
  kloop (0, k)
end // end of [kfindz]

val K0 = lam (res: int): ans_t =<cloref1> res

val kz1 = kfindz (kpoly1, K0)
val () = printf ("kz1 = %i\n", @(kz1))

(* ****** ****** *)

implement main () = ()

(* ****** ****** *)

(* end of [findz.dats] *)