This has been processed with:

ocamlorn --library stdlib.mli \ --library tuple.in.ml --input tuple.in.ml --lifting tuple.lif.ml \ > tuple.out.ml |

let f t = match t with (x,y) -> ((),x) |

type ornament ('a, 'b) rev : ('a * 'b) => ('b * 'a) with | (x,y) => (y,x) |

let rev_f = lifting f with ornament * <- rev, @id |

let f1 = f let f2 = f |

let f1' = lifting f1 with ornament * <- @id let f2' = lifting f2 with ornament * <- @id |

(* Test the moving of lets *)
let g t =
let x = f1 t in
let y = f2 t in
(x, y)
let h t =
(f1 t, f2 t) |

let g_id = lifting g with ornament * <- @id let g_rev = lifting g with ornament * <- rev, @id let h_id = lifting h with ornament * <- @id let h_rev = lifting h with ornament * <- rev, @id let f_test = lifting f : (_ * _) -> (unit * _) |

let rev_f t = match t with | (_, y) -> (y, ()) let f1' = rev_f let f2' = rev_f let g_id t = let x = f1' t in let y = f2' t in (x, y) let g_rev t = let x = f1' t in let y = f2' t in (y, x) let h_id t = (f1' t, f2' t) let h_rev t = let y = f2' t in (y, f1' t) let f_test t = match t with | (x, _) -> ((), x) |