1
votes

real basic question here: I'm new to Ocaml and I'm having issues trying to manipulate lists. I've read http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html, and I'm unfortunately still confused....I'm new to functional programming.

If I have, say, the following function:

  let stoverfl list1 list2 list3 =
      match list1 with
      |[]->None
      |h::list1 -> (*what I want to do goes in here*)

I want to take a look at the first elements of list2 and list3, compare them, and if they're equal, add the first element of list3 to list2, else don't modify the lists. I don't really care about error checking now (i.e. checking to see if the list has at least one element, etc.).

My attempt:

 h::list1 -> let cmp1 = hd list2 (*this should return the first elemnt of list2??*)
             let cmp2 = hd list3
             if(cmp1=cmp2) then
                let updlist2 = concat list2 hd list3
                let updlist3 = hd list3
                (*pass updlist2 and updlist3 instead of list2 and list3 to next function*)
             else
                (*do nothing; pass list2 and list3 as normal*)

I feel like I'm doing it all wrong...any advice would be appreciated! Thanks.

1

1 Answers

1
votes

You say you want to add the first element of list3 to list2. When a functional programmer says something like this what it means is that they want to construct a new list as described. You can't actually modify list2--lists are immutable and names are permanently bound to a single value. In fact, it seems like you want to construct two new lists. One of them has the first element of list2 at the front of list3. The other one is the remainder of list2 (all but the first element).

Assuming this is what you mean, and assuming you're not worried whether the lists are empty, then here's one way to get these values:

let updlist2 = List.tl list2 in
let updlist3 = (List.hd list2) :: list3

It's actually pretty close to what you wrote.

However, I wonder what you're going to do with these values next. If you want to pass them along to another function, it would be more normal to have the lets outside the if. As an example, here's some code that calls a function g with either a list, or the tail of the list, depending on the first element of the list:

let arg_for_g =
    match the_list with
    | [] -> []  (* No tail of the list *)
    | head :: tail -> if head = 3 then tail else the_list
in
    g arg_for_g

If you put the lets inside the if, you'll need to code two different calls to your next function. That could be fine, it depends on exactly what you're going to do with your values.

(As a side note, you should worry about whether the lists are empty! If you use a match statement you can detect that case pretty easily.)