+
+ (* insert 3 {[1;2]} ~~> {[ {[3;1;2]}; {[1;3;2]}; {[1;2;3]} ]} *)
+ let rec insert a u =
+ plus
+ (unit (Wrapped.bind u (fun us -> Wrapped.unit (a :: us))))
+ (Wrapped.bind u (fun us -> match us with
+ | [] -> zero ()
+ | x::xs -> (insert a (Wrapped.unit xs)) >>= fun v -> unit (Wrapped.bind v (fun vs -> Wrapped.unit (x :: vs)))))
+
+ (* select {[1;2;3]} ~~> {[ (1,{[2;3]}); (2,{[1;3]}), (3;{[1;2]}) ]} *)
+ let rec select u =
+ Wrapped.bind u (fun us -> match us with
+ | [] -> zero ()
+ | x::xs -> plus (unit (x, Wrapped.unit xs))
+ (select (Wrapped.unit xs) >>= fun (x', xs') -> unit (x', Wrapped.bind xs' (fun ys -> Wrapped.unit (x :: ys)))))
+
+ (* permute {[1;2;3]} ~~> {[ {[1;2;3]}; {[2;1;3]}; {[2;3;1]}; {[1;3;2]}; {[3;1;2]}; {[3;2;1]} ]} *)
+
+ let rec permute u =
+ Wrapped.bind u (fun us -> match us with
+ | [] -> unit (zero ())
+ | x::xs -> permute (Wrapped.unit xs) >>= (fun v -> insert x v))
+