(* CSCI 3155: Lambda Calculus *) (* Booleans *) val true_ = fn x => (fn y => x) val false_ = fn x => (fn y => y) fun ifthenelse_ a b c = a b c val ift = ifthenelse_ true_ "b" "c" val iff = ifthenelse_ false_ "b" "c" fun or_ a b = a (true_) b fun decbool b = b true false val ortt = decbool (or_ true_ true_) val ortf = decbool (or_ true_ false_) val orft = decbool (or_ false_ true_) val orff = decbool (or_ false_ false_) fun and_ a b = a b false_ val andtt = decbool (and_ true_ true_) val andtf = decbool (and_ true_ false_) val andft = decbool (and_ false_ true_) val andff = decbool (and_ false_ false_) fun not_ a = a false_ true_ val nott = decbool (not_ true_) val notf = decbool (not_ false_) (* Pairs *) (* What can we do with a pair? We can access one of its elements (i.e., "field access") *) fun pair_ x y = fn b => b x y (* fn b => _ifthenelse b x y *) fun fst_ p = p true_ fun snd_ p = p false_ val fstab = fst_ (pair_ "a" "b") val sndab = snd_ (pair_ "a" "b") (* Natural Numbers *) (* What can we do with a natural number? *) val n0 = fn f => fn z => z val n1 = fn f => fn z => f z val n2 = fn f => fn z => f (f z) val n3 = fn f => fn z => f (f (f z)) fun decint n = n (fn x => x + 1) 0 val dec0 = decint n0 val dec3 = decint n3 (* successor *) fun succ_ n = fn f => fn z => f (n f z) val decsucc0 = decint (succ_ n0) fun encint (i: int) = fn f => fn z => case i of 0 => z | i => f (encint (i-1) f z) val decenc5 = decint (encint 5) fun iszero_ n = n (fn x => false_) true_ val isz0 = decbool (iszero_ n0) val isz3 = decbool (iszero_ n3) fun plus_ m n = fn f => fn z => (m f) ((n f) z) fun plus_' m n = m succ_ n fun mult_ m n = fn f => n (m f) fun mult_' m n = m (plus_ n) n0 val plus1_1 = decint (plus_ n1 n1) val mult3_2 = decint (mult_ n3 n2) val plus1_1' = decint (plus_' n1 n1) val mult3_2' = decint (mult_' n3 n2) fun exp_ m n = n m val exp2_3 = decint (exp_ n2 n3) (* challenge *) (* fun pred_ n = val pred1 = decint (pred_ n1) val pred0 = decint (pred_ n0) *)