views:

451

answers:

3

How can i implement this function?

let rec append l i =

(* For example, if l is a list [1;2] and i is an integer 3
          append [1;2] 3 = [1;2;3]*)

;;

+3  A: 

The easy answer is:

let append l i = l @ [i]

List-append is provided as the infix function @ in ocaml, so there is no need to roll your own. It is not tail recursive in the default ocaml distribution, but you can use extlib and begin your source file with:

open Extlib
open ExtList

And that provides a tail-recursive @ implementation. You can also use batteries or Jane Street Core for a tail-recursive append.

David Crawshaw
You could do `List.rev_append (List.rev l1) l2` if you wanted to do it tail-recursively
newacct
btw, no need to open both Extlib and ExtList, either one would suffice.
ygrek
I am trying to do it the hard way without the @ function..how would I do that?
Polly Hollanger
+2  A: 

Without using an existing append function, or even any existing function, only pattern matching:

let rec insert_at_end l i =
  match l with
    [] -> [i]
  | h :: t -> h :: (insert_at_end t i)

# insert_at_end [1;2] 3  ;;
- : int list = [1; 2; 3]

Also note that most of OCaml's standard library is written in OCaml. You can get the source code for the function that you want, or in this case, almost the function that you want, by reading the source package. In this case:

file ocaml-3.11.1/stdlib/pervasives.ml

(* List operations -- more in module List *)

let rec (@) l1 l2 =
  match l1 with
    [] -> l2
  | hd :: tl -> hd :: (tl @ l2)
Pascal Cuoq
A: 

Here's one tail-recursive implementation, if you want to do everything by hand (and that's not so difficult).

First, a function that reverses a list:

let mirror l =
    let rec aux accu = function
    | [] -> accu
    | h::t -> aux (h::accu) t
in aux [] l

The use of an auxiliary function is quit common to achieve tail-recursivity.

Now the actual "append" function:

let append l i = mirror (i::(mirror l))
jdb