The safe implementation is as follows:
let rot1 l = let rec aux acc = function [] -> [] | [x] -> x :: List.rev acc | x :: l -> aux (x :: acc) l in aux [] l
This is safe in the sense that passing an empty list returns an empty list instead of raising an exception. Please note that I strongly recommend against using List.hd and List.tl, because they can fail with a common error message.
Also, the aux recursive call is a tail call (the last thing to do before returning). OCaml compilers will detect this and will not grow the stack with every function call (and possibly throw an exception or crash). This is what you need to know about when working with long lists and recursive functions.
To make this operation efficiently, i.e. in O (1), not O (length), you cannot use a regular list. You can use the Queue module from the standard library or the implementation of doubly linked lists provided by third parties.
Here is an example of using the Queue module:
let rotate_queue q = if not (Queue.is_empty q) then let x = Queue.take q in Queue.add xq # let q = Queue.create ();; val q : '_a Queue.t = <abstr> # Queue.add 1 q;; - : unit = () # Queue.add 2 q;; - : unit = () # Queue.add 3 q;; - : unit = () # Queue.iter print_int q;; 123- : unit = () # rotate_queue q;; - : unit = () # Queue.iter print_int q;; 231- : unit = () #
source share