(* the factorial function *) let fact = fix (lam (f: int -> int) (n: int) => if n = 0 then 1 else n * f (n-1)) in fact (10) (* here is the parse tree of the program: TtmLet ("fact", TtmFix (TtmLam ("f",TpFun (TpBase "int",TpBase "int"), TtmLam ("n",TpBase "int", TtmIf (TtmOp ("=",[TtmVar "n",TtmInt 0]),TtmInt 1, TtmOp ("*", [TtmVar "n", TtmApp (TtmVar "f",TtmOp ("-",[TtmVar "n",TtmInt 1]))]))))), TtmApp (TtmVar "fact",TtmInt 10)) *) (* the even and odd functions *) let evenodd = fix (lam (eo: (int -> bool) * (int -> bool)) => (lam (n: int) => if n = 0 then true else eo.2 (n-1), lam (n: int) => if n = 0 then false else eo.1 (n-1))) in let even = evenodd.1 in let odd = evenodd.2 in (even 9, odd 26) (* here is the parse tree of the above program: TtmLet ("evenodd", TtmFix (TtmLam ("eo", TpTup [TpFun (TpBase "int",TpBase "bool"), TpFun (TpBase "int",TpBase "bool")], TtmTup [TtmLam ("n",TpBase "int", TtmIf (TtmOp ("=",[TtmVar "n",TtmInt 0]),TtmBool true, TtmApp (TtmPro (TtmVar "eo",2), TtmOp ("-",[TtmVar "n",TtmInt 1])))), TtmLam ("n",TpBase "int", TtmIf (TtmOp ("=",[TtmVar "n",TtmInt 0]),TtmBool false, TtmApp (TtmPro (TtmVar "eo",1), TtmOp ("-",[TtmVar "n",TtmInt 1]))))])), TtmLet ("even",TtmPro (TtmVar "evenodd",1), TtmLet ("odd",TtmPro (TtmVar "evenodd",2), TtmTup [TtmApp (TtmVar "even",TtmInt 9), TtmApp (TtmVar "odd",TtmInt 26)]))) *) (* a higher-order example *) let find_zero = lam (f: int -> int) => letrec g: int -> int = lam (n: int) => if f (n) = 0 then n else g (n+1) in g (0) in find_zero (lam (n: int) => (n * n - n - 10100)) (* here is the parse tree of the above example: TtmLet ("find_zero", TtmLam ("f",TpFun (TpBase "int",TpBase "int"), TtmLetrec ("g",TpFun (TpBase "int",TpBase "int"), TtmLam ("n",TpBase "int", TtmIf (TtmOp ("=",[TtmApp (TtmVar "f",TtmVar "n"),TtmInt 0]), TtmVar "n", TtmApp (TtmVar "g",TtmOp ("+",[TtmVar "n",TtmInt 1])))), TtmApp (TtmVar "g",TtmInt 0))), TtmApp (TtmVar "find_zero", TtmLam ("n",TpBase "int", TtmOp ("-", [TtmOp ("-",[TtmOp ("*",[TtmVar "n",TtmVar "n"]),TtmVar "n"]), TtmInt 10100])))) *) (* What does the following program do? * The execution of this program may take a while to terminate: * please pay attention to the text printed out on your display. *) let abs = lam (x: int) => if x >= 0 then x else 0 - x in letrec dots_pr: int -> unit = lam (n: int) => if n = 0 then () else let _ = print (".") in dots_pr (n-1) in let row_pr = lam (n: int) => let _ = dots_pr (n-1) in let _ = print ("Q") in let _ = dots_pr (8-n) in let _ = print ("\n") in () in let board_pr = lam (bd: int * (int * (int * (int * (int * (int * (int * int))))))) => let _ = row_pr (bd.1) in let bd = bd.2 in let _ = row_pr (bd.1) in let bd = bd.2 in let _ = row_pr (bd.1) in let bd = bd.2 in let _ = row_pr (bd.1) in let bd = bd.2 in let _ = row_pr (bd.1) in let bd = bd.2 in let _ = row_pr (bd.1) in let bd = bd.2 in let _ = row_pr (bd.1) in row_pr (bd.2) in let test2 = lam (x: int * int) => let x1 = x.1 in let x2 = x.2 in if x1 = x2 then false else if abs (x1 - x2) = 1 then false else true in let test_2 = lam (xyn: int * ((int * int) * int)) => let x = xyn.1 in let yn = xyn.2 in let y = yn.1 in let n = yn.2 in let y1 = y.1 in let y2 = y.2 in if x = y1 then false else if abs(x-y1) = n+1 then false else if x = y2 then false else if abs (x-y2) = n+2 then false else true in let test3 = lam (x: int * (int * int)) => let x1 = x.1 in let x2 = x.2 in if test_2 (x1, (x2, 0)) then test2 (x2) else false in let test_3 = lam (xyn: int * ((int * (int * int)) * int)) => let x = xyn.1 in let yn = xyn.2 in let y = yn.1 in let n = yn.2 in let y1 = y.1 in let y2 = y.2 in if x = y1 then false else if abs(x-y1) = n+1 then false else test_2 (x, (y2, n+1)) in let test4 = lam (x: int * (int * (int * int))) => let x1 = x.1 in let x2 = x.2 in if test_3 (x1, (x2, 0)) then test3 (x2) else false in let test_4 = lam (xyn: int * ((int * (int * (int * int))) * int)) => let x = xyn.1 in let yn = xyn.2 in let y = yn.1 in let n = yn.2 in let y1 = y.1 in let y2 = y.2 in if x = y1 then false else if abs(x-y1) = n+1 then false else test_3 (x, (y2, n+1)) in let test5 = lam (x: int * (int * (int * (int * int)))) => let x1 = x.1 in let x2 = x.2 in if test_4 (x1, (x2, 0)) then test4 (x2) else false in let test_5 = lam (xyn: int * ((int * (int * (int * (int * int)))) * int)) => let x = xyn.1 in let yn = xyn.2 in let y = yn.1 in let n = yn.2 in let y1 = y.1 in let y2 = y.2 in if x = y1 then false else if abs(x-y1) = n+1 then false else test_4 (x, (y2, n+1)) in let test6 = lam (x: int * (int * (int * (int * (int * int))))) => let x1 = x.1 in let x2 = x.2 in if test_5 (x1, (x2, 0)) then test5 (x2) else false in let test_6 = lam (xyn: int * ((int * (int * (int * (int * (int * int))))) * int)) => let x = xyn.1 in let yn = xyn.2 in let y = yn.1 in let n = yn.2 in let y1 = y.1 in let y2 = y.2 in if x = y1 then false else if abs(x-y1) = n+1 then false else test_5 (x, (y2, n+1)) in let test7 = lam (x: int * (int * (int * (int * (int * (int * int)))))) => let x1 = x.1 in let x2 = x.2 in if test_6 (x1, (x2, 0)) then test6 (x2) else false in let test_7 = lam (xyn: int * ((int * (int * (int * (int * (int * (int * int)))))) * int)) => let x = xyn.1 in let yn = xyn.2 in let y = yn.1 in let n = yn.2 in let y1 = y.1 in let y2 = y.2 in if x = y1 then false else if abs(x-y1) = n+1 then false else test_6 (x, (y2, n+1)) in let test8 = lam (x: int * (int * (int * (int * (int * (int * (int * int))))))) => let x1 = x.1 in let x2 = x.2 in if test_7 (x1, (x2, 0)) then test7 (x2) else false in letrec incs: (int -> unit) * (int * int -> unit) * (int * (int * int) -> unit) * (int * (int * (int * int)) -> unit) * (int * (int * (int * (int * int))) -> unit) * (int * (int * (int * (int * (int * int)))) -> unit) * (int * (int * (int * (int * (int * (int * int))))) -> unit) * (int * (int * (int * (int * (int * (int * (int * int)))))) -> unit) = (lam (x:int) => if x < 8 then incs.2 (0, x+1) else (), lam (xy: int * int) => let x = xy.1 in let y = xy.2 in if (x < 8) then if test2 (x+1, y) then incs.3 (0, (x+1, y)) else incs.2 (x+1, y) else incs.1 (y), lam (xy: int * (int * int)) => let x = xy.1 in let y = xy.2 in if (x < 8) then if test3 (x+1, y) then incs.4 (0, (x+1, y)) else incs.3 (x+1, y) else incs.2 (y), lam (xy: int * (int * (int * int))) => let x = xy.1 in let y = xy.2 in if (x < 8) then if test4 (x+1, y) then incs.5 (0, (x+1, y)) else incs.4 (x+1, y) else incs.3 (y), lam (xy: int * (int * (int * (int * int)))) => let x = xy.1 in let y = xy.2 in if (x < 8) then if test5 (x+1, y) then incs.6 (0, (x+1, y)) else incs.5 (x+1, y) else incs.4 (y), lam (xy: int * (int * (int * (int * (int * int))))) => let x = xy.1 in let y = xy.2 in if (x < 8) then if test6 (x+1, y) then incs.7 (0, (x+1, y)) else incs.6 (x+1, y) else incs.5 (y), lam (xy: int * (int * (int * (int * (int * (int * int)))))) => let x = xy.1 in let y = xy.2 in if (x < 8) then if test7 (x+1, y) then incs.8 (0, (x+1, y)) else incs.7 (x+1, y) else incs.6 (y), lam (xy: int * (int * (int * (int * (int * (int * (int * int))))))) => let x = xy.1 in let y = xy.2 in if (x < 8) then if test8 (x+1, y) then let _ = board_pr (x+1, y) in let _ = print ("\n") in incs.8 (x+1, y) else incs.8 (x+1, y) else incs.7 (y)) in incs.1 (0)