We need to activate autolifting for this:

#(mode autolift) #(mode unfold)

We define lists:

type 'a list = | Nil | Cons of 'a * 'a list

And a map function:

let rec map f x = match x with | Nil -> Nil | Cons(x,xs) -> Cons(f x, map f xs)

We want to use vectors of three elements:

type 'a vec3 = Vec3 of 'a * 'a * 'a

They are a specialization of lists:

type ornament 'a list3 : 'a list => 'a vec3 with | Nil => ~ | Cons(x, (y, z) : 'a list2) => Vec3(x, y, z) and 'a list2 : 'a list => 'a * 'a with | Nil => ~ | Cons(y, z : 'a list1) => (y, z) and 'a list1 : 'a list => 'a with | Nil => ~ | Cons(z, () : 'a list0) => z and 'a list0 : 'a list => () with | Nil => () | Cons(x, xs) => ~
#(push_env) let map_tuple = lifting map : ('a -> 'b) -> 'a list3 -> 'b list3 #(pop_env)
let rec map_tuple f x = match x with | Vec3(x, y, z) -> begin match map_auto1 f (y, z) with | (y, z) -> Vec3(f x, y, z) end and map_auto1 f x = match x with | (x, x1) -> (f x, map_auto2 f x1) and map_auto2 f x = match map_auto3 f () with | () -> f x and map_auto3 f x = match x with | () -> ()

We can request inlining for this definition:

#(mode inline) let map_tuple = lifting map : ('a -> 'b) -> 'a list3 -> 'b list3
let map_tuple f x = match x with | Vec3(x, y, z) -> Vec3(f x, f y, f z)