fun map (f, l) = match (l) { N -> N | C (x, xs) -> C (f (x), map (f, xs)) } fun concat (l1, l2) = match (l1) { N -> l2 | C (x, xs) -> C (x, concat (xs, l2)) } fun flatten (l) = match (l) { N -> N | C (l, ls) -> concat (l, flatten (ls)) } fun return (x) = C (x, N) fun bind (x, f) = flatten (map (f, x)) let fail = N fun some d = C (d, N) fun range (start, stop) = if (start >? stop) then { N } else { C (start, range (start + 1, stop)) } fun all_sums (start, stop, n) = bind (range (start, stop), \x -> bind (range (start, stop), \y -> if (x + y =? n) then { return (some (x, y, n)) } else { fail } )) fun show_sum (x, y, n) = print_int (x); print_string (" + "); print_int (y); print_string (" = "); print_int (n); print_string ("\n") fun iter (f, l) = match (l) { N -> nothing | C (x, xs) -> f (x); iter (f, xs) } let test = iter (show_sum, flatten (all_sums (13, 73, 73)))